मैं हर तरह के फ्रैक्टल्स (जैसे मेरा वीडियो को रेंडर करने के लिए अपना खुद का ग्राफिक्स इंजन विकसित कर रहा हूं। यहां उदाहरण के लिए), और मैं वर्तमान में जूलिया सेट मेटिंग्स के लिए अपना कोड अनुकूलित करने पर काम कर रहा हूं (देखें यह प्रश्न और मेरी परियोजना अधिक जानकारी के लिए)। खंड शेडर में, मैं इस फ़ंक्शन का उपयोग करता हूं:

vec3 JuliaMatingLoop(dvec2 z)
{
    ...

    for (int k = some_n; k >= 0; --k)
    {
        // z = z^2
        z = dcproj(c_2(z));
        
        // Mobius Transformation: (ma[k] * z + mb[k]) / (mc[k] * z + md[k])
        z = dcproj(dc_div(cd_mult(ma[k], z) + mb[k], dc_mult(mc[k], z) + md[k]));
    }
    
    ...
}

और यह पढ़ने के बाद, मुझे एहसास हुआ कि मैं इसमें मोबियस ट्रांसफॉर्मेशन कर रहा हूं कोड, और (गणितीय रूप से बोलना) मैं उसी ऑपरेशन को पूरा करने के लिए मैट्रिसेस का उपयोग कर सकता हूं। हालांकि, a, b, c, और d स्थिरांक सभी सम्मिश्र संख्याएं हैं ( के रूप में प्रदर्शित) ma[k], mb[k], mc[k], और md[k] मेरे कोड में), जबकि GLSL मैट्रिक्स में तत्वों में केवल वास्तविक संख्याएँ होती हैं (vec2 के बजाय)। और इसलिए मेरे प्रश्न के लिए: क्या जीएलएसएल में मैट्रिस का उपयोग करके इन मोबियस परिवर्तनों को अनुकूलित करने का कोई तरीका है? या मेरे कोड के इस हिस्से को अनुकूलित करने का कोई अन्य तरीका?

सहायक कार्य (मुझे इस भाग के लिए युगल का उपयोग करने की आवश्यकता है, इसलिए मैं फ़्लोट्स का उपयोग करके स्विच करके अनुकूलित नहीं कर सकता):

// Squaring
dvec2 c_2(dvec2 c)
{
    return dvec2(c.x*c.x - c.y*c.y, 2*c.x*c.y);
}
// Multiplying
dvec2 dc_mult(dvec2 a, dvec2 b)
{
    return dvec2(a.x*b.x - a.y*b.y, a.x*b.y + a.y*b.x);
}
// Dividing
dvec2 dc_div(dvec2 a, dvec2 b)
{
    double x = b.x * b.x + b.y * b.y;
    return vec2((a.x * b.x + a.y * b.y) / x, (b.x * a.y - a.x * b.y) / x);
    
}
// Riemann Projecting
dvec2 dcproj(dvec2 c)
{
    if (!isinf(c.x) && !isinf(c.y) && !isnan(c.x) && !isnan(c.y))
        return c;
        
    return dvec2(infinity, 0);
}
0
Ibrahim Mahmoud 19 जुलाई 2020, 09:14

1 उत्तर

सबसे बढ़िया उत्तर

मुझे यकीन नहीं है कि इससे मदद मिलेगी, लेकिन हाँ आप मैट्रिस द्वारा जटिल अंकगणित कर सकते हैं।

यदि आप एक सम्मिश्र संख्या z को वास्तविक दो-सदिश के रूप में घटकों Re(z), Im(z) के साथ देखते हैं तो

A*z + B ~ (Re(A)  -Im(A) ) * (Re(z)) + (Re(B))
          (Im(A)   Re(A) )   (Im(z))   (Im(B))

बेशक आप वास्तव में चाहते हैं

(A*z + B) / (C*z + D)

यदि आप गणना करते हैं

A*z+b as (x)
         (y)

C*z+d as (x')
         (y')

तब आप जो उत्तर चाहते हैं वह है

inv( x' -y') * ( x)
   ( y' x' )   ( y)
i.e
    (1/(x'*x'+y'*y')) * (x'  y') * (x)
                        (-y' x')   (y)

हालांकि, ध्यान देने वाली एक बात यह है कि इन फ़ार्मुलों में, जैसा कि आपके कोड में है, विभाजन को उतनी मजबूती से लागू नहीं किया गया है जितना हो सकता है। समस्या b.x * b.x + b.y * b.y का मूल्यांकन करने में है। यह अनंत तक अतिप्रवाह हो सकता है, या 0 तक कम हो सकता है, भले ही विभाजन का परिणाम काफी उचित हो। इसके लिए आमतौर पर इस्तेमाल किया जाने वाला तरीका स्मिथ का तरीका है जैसे यहां और अगर आप 'मजबूत जटिल विभाजन' की खोज करते हैं तो आपको हाल ही का काम मिलेगा। अक्सर इस तरह की बात बहुत कम मायने रखती है, लेकिन अगर आप अनंत तक पुनरावृति कर रहे हैं तो इससे फर्क पड़ सकता है।

0
dmuir 2 अगस्त 2020, 15:33