2010-10-04 8 views
5

के अंदर शुरू होती हैं तो अपवर्तन से निपटने के लिए कैसे करें मैं शैक्षणिक उद्देश्यों के लिए एक साधारण रेएटरर बना रहा हूं और वस्तुओं को अपवर्तन जोड़ना चाहता हूं। Snells कानून का उपयोग करके, मैं चौराहे बिंदु पर एक नई किरण बनाने में सक्षम हूँ। रेट्रेटर वर्तमान में केवल गोलाकारों का समर्थन करता है और मैं एक दृश्य का उपयोग करता हूं जहां मेरे पास अलग-अलग अपवर्तन सूचकांक के साथ एक दूसरे के अंदर घोंसले हुए कई गोले होते हैं।जब किरणें नेस्टेड ऑब्जेक्ट

यदि मैं गोलाकारों के बाहर से एक किरण शुरू करता हूं, तो सबकुछ सरल लगता है। आप दृश्य के अपवर्तन सूचकांक से शुरू करते हैं, और जैसे ही आप पहले क्षेत्र को हिट करते हैं, पहले रेफ्रेक्शन इंडेक्स का उपयोग करके रे को अपवर्तित करें और क्षेत्र के भौतिक सामग्री के अपवर्तन सूचकांक को तब तक अपवर्तित करें जब तक कि आप अगले क्षेत्र को हिट न करें। चौराहे के मानकों का उपयोग करके मैं निर्धारित कर सकता हूं कि मैं क्षेत्र में प्रवेश करता हूं या छोड़ देता हूं।

हालांकि, मुझे समझ में नहीं आता कि मुझे गोलाकारों को कैसे संभालना चाहिए और दृश्य के बाहरी भाग में किरण शुरू नहीं होने पर क्या करना है।

  • क्या मैं केवल अपवर्तन सूचकांक का ढेर ले सकता हूं और जैसे ही मैं एक क्षेत्र छोड़ता हूं, एक परत ऊपर जा सकता हूं?
  • यदि मैं गोलाकारों के अंदर शुरू करता हूं तो मुझे कैसे अपवर्तन सूचकांक शुरू करना है, मैं कैसे निर्धारित कर सकता हूं?

उदाहरण

साथ अपवर्तन भीतरी 0.9, 1.1 और 0.8 बाहरी से सूचकांक आप तीन क्षेत्रों की है।

  • शुरू सूचकांक 1.0 है, तो आपको पहले सूचकांक 0.9 के साथ बाहरी क्षेत्र मारा और से सीधे रास्ते से फेर: एयर सूचकांक 1,0

    • आपका कैमरा गोले के केंद्र में क्षेत्र और अंक के बाहर है 1.0 से 0.9 और सहेजें कि आपकी किरण अब 0.9 सामग्री

    • पर आप मध्य क्षेत्र को हिट करते हैं और 1.1 की सामग्री स्थिरता देखते हैं, क्योंकि आपने 0.9 को सहेजा है, आपको पता है कि आपको 0.9 से 1.1 तक अपवर्तित करना है और सहेजना है 1.1 0.9
    • के अलावा आप हिट करते हैं आंतरिक क्षेत्र और 1.1 से 0.8 तक अपवर्तित है और आपने अब तक 0.9, 1.1 और 0.8
    • को सहेज लिया है, फिर भी आप आंतरिक क्षेत्र फिर से दबाते हैं (इस बार आप इसे बाहर निकलेंगे, इसलिए आप अपने सहेजे गए मानों की जांच करें और जानें कि आपको वापस स्विच करना है 1.1)
    • ... जब तक आप बाहर, अब
  • समस्या हैं जब कैमरा क्षेत्र के अंदर है। आपको यह नहीं पता होगा कि आपको किस अपवर्तन सूचकांक को स्विच करना है।

+0

बस एक नोट पर उपलब्ध, कि अपवर्तक होना चाहिए अधिक से अधिक> = 1, मेरा उत्तर में समीकरण के लिए नीचे होने वैध। यही है, जब तक कि आप रे ट्रेसिंग मेटा-सामग्री में दिलचस्पी नहीं रखते हैं :) –

उत्तर

1

भौतिकी बिंदु से इसे पोस्ट करना और एक रेट्रैसिंग कार्यान्वयन बिंदु नहीं: पी।

स्नेल का कानून बताता है कि घटना कोण और अपवर्तक कोण की साइनों का अनुपात सीमा के दोनों तरफ दोनों माध्यमों के अपवर्तक सूचकांक के अनुपात के विपरीत के बराबर है।

इस प्रकार, जब आपके पास एक नई सामग्री के पास एक किरण है और आप नई सामग्री में कोण जानना चाहते हैं, तो आपको उस कोण को जानना होगा कि रे नई सामग्री को मार रहा है, नई सामग्री के अपवर्तन की सूचकांक , और वर्तमान में किरण सामग्री के अपवर्तन की सूचकांक है।

जैसा कि आप कहते हैं कि अपवर्तन कार्य क्षेत्र में बढ़ते काम करता है, आपको पहले से ही प्रत्येक क्षेत्र और आपके दृश्य के अपवर्तन की अनुक्रमणिका जाननी चाहिए।

मैं कहूंगा कि अपवर्तक सूचकांक का ढेर बनाना घोंसला वाली सामग्री के समूह में जाने से निपटने का एक अच्छा तरीका होगा, क्योंकि आपको फिर से स्टैक पर धक्का देने वाली सभी अपवर्तक अनुक्रमणिका को छूना होगा जैसे ही आप गोलाकारों के घोंसले के सेट से बाहर निकलते हैं।

यह निर्धारित करने के लिए कि आप गोलाकार छोड़ने के साथ किस अपवर्तक सूचकांक को शुरू करना चाहते हैं, आप हमेशा पाप (theta1)/sin (theta2) = [2 का अपवर्तक सूचकांक]/[अपवर्तक सूचकांक 1] कह रहे हैं। इस प्रकार, आपको उस सामग्री की अपवर्तक अनुक्रमणिका की आवश्यकता है जिसमें आप वर्तमान में हैं और उस सामग्री की अनुक्रमणिका जो आप आगे बढ़ने जा रहे हैं।

क्षमा करें अगर मैंने आपके प्रश्न को गलत समझा, लेकिन मुझे उम्मीद है कि इससे मदद मिलती है!

+0

हां, लेकिन अगर आपका कैमरा नेस्टेड सामग्री के अंदर है और आप बाहर से देख रहे हैं तो आप क्या करते हैं? ;-) – Etan

9

मेरे पास एक समान रे ट्रेसर (पायथन में लिखा गया है) है और एक ही समस्या पर ठोकर खाई है: भौतिकी को सही तरीके से काम करने के लिए एक को चौराहे सीमा के प्रत्येक तरफ अपवर्तक सूचकांक को अवश्य जानना चाहिए। इस सुंदर ढंग से हल करने के लिए काफी समय लगा, लेकिन अंत में मैं इस समाधान/डिजाइन के साथ चला गया:

डिजाइन

1) दृश्य - मैं एक मास्टर दृश्य वस्तु है (मूल रूप से एक सभी वस्तुओं की सरणी दृश्य में), आप शायद कुछ समान होगा। यह ज्यामितीय वस्तुओं को स्टोर करता है।

तरीके:

  • intersection_points(ray) - सभी चौराहे अंक, रे से दूरी के अनुसार क्रमबद्ध की एक सूची देता है।
  • intersection_objects(ray) - किरण से दूरी से क्रमबद्ध सभी चौराहे वस्तुओं की एक सूची देता है।
  • containing_object(ray) - उस वस्तु को लौटाता है जिसमें किरण है।
  • objects() - मनमानी क्रम में सभी वस्तुओं की एक सूची देता है।

नोट: Scene_Boundary: दृश्य सूची के लिए एक अतिरिक्त वस्तु कहते हैं। यह एक विशाल बॉक्स (या क्षेत्र) है जो पूरे दृश्य को घेरता है यानी इस सीमा के अंदर सबकुछ है।

2) ऑब्जेक्ट्स - ज्यामितीय वस्तुओं (जैसे आपका क्षेत्र) इन विधियों को लागू करें।

तरीके:

  • contains(ray) - यह सच है देता है रे सतह पर है - यह सच है देता है रे मूल, ऑब्जेक्ट के अंदर है झूठी अगर सतह पर और झूठी अगर बाहर
  • ray_is_on_surface(ray) है केवल, अन्यथा झूठा।
  • intersection_points(ray) - रिटर्न प्रतिच्छेदन बिंदु (रों) कि रे वस्तु
  • surface_normal(ray) के साथ बनाता है - सतह सतह है जो रे मारा के सामान्य वेक्टर
(इस Fresnel प्रतिबिंब और अपवर्तन के साथ में मदद मिलेगी) रिटर्न

ऑप्टिकल गणना के लिए वस्तुओं में एक अपवर्तक सूचकांक भी होना चाहिए।

उदाहरण चर: अपवर्तनांक अंदर की (n1) और बाहर (एन 2) क्या है:

  • refractive_index

सीमा समस्या

समस्या

हम हल करना चाहते सीमा? ऐसा करने के लिए हम इस प्रक्रिया का पालन:

1) पूरे दृश्य के माध्यम से रे ट्रेस: ​​

sphere # origin = (0,0,0), radius = 1 
ray # origin = (0,0,0), direction = (0,0,1) Note: the ray is inside the sphere 
scene.add_object(sphere) 
ipoints = scene.intersection_points(ray) # [ (0,0,1), (0,0,10) ] 
iobjects = scene.intersection_objects(ray) # [ Sphere, Scene_Boundary] 

याद रखें इन रे मूल से दूरी के अनुसार क्रमबद्ध कर रहे हैं। आईपॉइंट्स और आईबोजेक्ट्स में आखिरी वस्तु दृश्य सीमा के साथ किरण को छेड़छाड़ करती है। हम बाद में इसका इस्तेमाल करेंगे!

2) n1 युक्त वस्तु, उदा .:

obj1 = scene.containing_object(ray) # Scene_Boundary 
n1 = obj1.refractive_index() # n1 = 1. Scene_Boundary always has refractive index of Air 

3) n2 iobject सूची में आगे एक वस्तु देखकर पाया जाता है, उदा का पता लगाकर बस पाया जाता है स्यूडोकोड में:

normal = obj1.surface_normal(ray) 

आप सभी जानकारी आप सही प्रतिबिंब और अपवर्तन की गणना करने की जरूरत है:

index = iobjects.index_of_object(obj1) 
obj2 = iobjects[index+1] 
n2 = obj2.refractive_index() # n2 = 1.5 e.g. Glass 

4) सतह बाद में उपयोग के लिए सामान्य है। यह सामान्य रूप से काम करने के लिए पर्याप्त है, भले ही किरण वस्तु के बाहर है, लेकिन कभी-कभी मुझे एल्गोरिदम को और अधिक मजबूत बनाने के लिए कुछ लॉजिकल फ़िल्टरिंग को लागू करने की आवश्यकता होती है, लेकिन यह मूल रूप से यह है!

परावर्तन और अपवर्तन

तुम सिर्फ सतह सामान्य जानने से एक सदिश को प्रतिबिंबित कर सकते हैं। अजगर numpy का उपयोग करने में मैं इसे इस तरह करते हैं,

def reflect_vector(normal, vector): 
    d = numpy.dot(normal, vector) 
    return vector - 2 * d * normal 

अपवर्तन (के रूप में चर्चा) की जरूरत है N1 और N2 मान:

def fresnel_refraction(normal, vector, n1, n2): 
    n = n1/n2 
    dot = np.dot(norm(vector), norm(normal)) 
    c = np.sqrt(1 - n**2 * (1 - dot**2)) 
    sign = 1 
    if dot < 0.0: 
     sign = -1 
    refraction = n * vector + sign*(c - sign*n*dot) * normal 
    return norm(refraction) 

अंत में आप रे के लिए प्रतिबिंब गुणांक की गणना करने की आवश्यकता होगी जहां कोण रे दिशा और सतह सामान्य के बीच कोण है (यह माना जाता है कि आपकी किरण 'unpolarised' है)। प्रतिबिंब होने पर यह तय करने के लिए 0 और 1 के बीच एक यादृच्छिक संख्या के साथ तुलना करें।

def fresnel_reflection(angle, n1, n2): 
    assert 0.0 <= angle <= 0.5*np.pi, "The incident angle must be between 0 and 90 degrees to calculate Fresnel reflection." 
    # Catch TIR case 
    if n2 < n1: 
     if angle > np.arcsin(n2/n1): 
      return 1.0 

    Rs1 = n1 * np.cos(angle) - n2 * np.sqrt(1 - (n1/n2 * np.sin(angle))**2) 
    Rs2 = n1 * np.cos(angle) + n2 * np.sqrt(1 - (n1/n2 * np.sin(angle))**2) 
    Rs = (Rs1/Rs2)**2 
    Rp1 = n1 * np.sqrt(1 - (n1/n2 * np.sin(angle))**2) - n2 * np.cos(angle) 
    Rp2 = n1 * np.sqrt(1 - (n1/n2 * np.sin(angle))**2) + n2 * np.cos(angle) 
    Rp = (Rp1/Rp2)**2 
    return 0.5 * (Rs + Rp) 

अंतिम टिप्पणी

यह सब मेरी अजगर ऑप्टिकल रे अनुरेखण परियोजना जो अभी तक जारी नहीं किया गया है से आता है, लेकिन आप यहां कुछ विस्तार के लिए जाँच कर सकते हैं (!): http://daniel.farrell.name/freebies/pvtrace। मुझे पायथन पसंद है! यहां सूचीबद्ध कई पायथन रे ट्रेसिंग परियोजनाएं हैं, http://groups.google.com/group/python-ray-tracing-community/web/list-of-python-statistical-ray-tracers। अंत में, अपने उदाहरण में आंशिक अपवर्तक सूचकांक से सावधान रहें, समीकरण टूट जाएगा।

अद्यतन

यह मेरा रे ट्रेसर में लागू करने का स्क्रीनशॉट, http://github.com/danieljfarrell/pvtrace alt text

संबंधित मुद्दे