จุดตัดของเรย์-สเฟียร์: การแบ่งแยกนั้นผิด

เอาล่ะ ฉันกำลังสร้างเครื่องติดตามรังสีโดยใช้การแรเงาแบบฟอง จนถึงตอนนี้ทุกอย่างดี ฉันใช้รังสีที่กระทบทรงกลมในฉากของฉัน ใช้การแรเงาด้วยฟอง และมันก็ดูปกติ

ตอนนี้ ฉันกำลังคำนวณรังสีเงา ซึ่งจะยิงรังสีจากจุดตัดจากรังสีปฐมภูมิไปยังแหล่งกำเนิดแสง และดูว่ารังสีดังกล่าวกระทบกับวัตถุใดๆ ที่ขวางทางหรือไม่ หากเป็นเช่นนั้นแสดงว่าอยู่ในเงามืด

อย่างไรก็ตาม เมื่อคำนวณว่ารังสีเงากระทบกับทรงกลมใดๆ หรือไม่ ดูเหมือนว่าจะมีข้อผิดพลาดกับการแบ่งแยกของฉันที่คำนวณไว้ ซึ่งเป็นเรื่องแปลกเนื่องจากจนถึงขณะนี้รังสีปฐมภูมิถูกต้องแล้ว

นี่คือการตั้งค่า:

// Origin of ray (x,y,z)
origin: -1.9865333, 1.0925934, -9.8653316
// Direction of ray (x,y,z), already normalized
ray: -0.99069530, -0.13507602, -0.016648887

// Center of sphere (x,y,z)
cCenter: 1.0, 1.0, -10.0
// Radius of the sphere (x,y,z)
cRadius: 1.0

และนี่คือโค้ดสำหรับค้นหาผู้จำแนก:

// A = d DOT d
float a = dotProd(ray, ray);

// B = 2 * (o - c) DOT d
Point temp (2.0*(origin.getX() - cCenter.getX()), 2.0*(origin.getY() - cCenter.getY()), 2.0*(origin.getZ() - cCenter.getZ()));
float b = dotProd(temp, ray);

// C = (o - c) DOT (o - c) - r^2
temp.setAll(origin.getX() - cCenter.getX(), origin.getY() - cCenter.getY(), origin.getZ() - cCenter.getZ());
float c = dotProd(temp, temp);
c -= (cRadius * cRadius);

// Find the discriminant (B^2 - 4AC)
float discrim = (b*b) - 4*a*c; 

เห็นได้ชัดเจนว่ารังสีกำลังชี้ออกจากทรงกลม แต่ค่าจำแนกตรงนี้เป็นบวก (2.88) บ่งชี้ว่ารังสีกระทบทรงกลม และโค้ดนี้ใช้ได้ผลดีกับรังสีปฐมภูมิ เนื่องจากตัวจำแนกรังสีจะต้องถูกต้อง แต่ไม่ใช่สำหรับรังสีทุติยภูมิเหล่านี้

ฉันพลาดอะไรบางอย่างที่นี่หรือเปล่า?


person user1115016    schedule 25.12.2011    source แหล่งที่มา
comment
ฉันเดาว่าสิ่งที่คุณขาดหายไปคือความเข้าใจในคณิตศาสตร์และสิ่งที่บอกคุณ อัลกอริธึมนี้จะบอกคุณหรือไม่ว่า LINE ตัดกับทรงกลมซึ่งตรงข้ามกับรังสี นั่นคือเส้นตรงมีขอบเขตไม่สิ้นสุดในสองทิศทาง   -  person    schedule 25.12.2011
comment
@woodchips รังสีเป็นเวกเตอร์ (จุดที่มีทิศทาง) ดังนั้นจึงไม่มีที่สิ้นสุดในทิศทางเดียว (ทิศทางที่มันชี้) สูตรนี้ขึ้นอยู่กับฟังก์ชันของทรงกลม จุด P อยู่บนทรงกลมหากเป็นไปตามนั้น: ||P - Pc|| = r^2 โดยที่ Pc คือจุดศูนย์กลางของทรงกลม และ r คือรัศมี สำหรับรังสี จุด P จะอยู่บนรังสีถ้า P = Q + td โดยที่ Q คือจุดเริ่มต้นของรังสี d คือทิศทาง และ t คือเวลา นี่คือลิงค์ในกรณีที่คำอธิบายของฉันสั้น: wiki.cgsociety.org/index.php/Ray_Sphere_Intersection   -  person user1115016    schedule 25.12.2011
comment
ใช่. และในขณะที่คุณคัดลอกคำจำกัดความของเส้นและรังสีอย่างระมัดระวัง คุณก็ไม่ได้สนใจที่จะเข้าใจสมการที่ดำเนินต่อไปและนำสิ่งที่คุณอ้างอิงไปใช้ การแบ่งแยกเชิงบวกหรือเชิงลบไม่ได้หมายความว่ามีวิธีแก้สำหรับจุดตัดของรังสี มันบอกคุณว่ามีวิธีแก้ปัญหาสำหรับ LINE ที่ไม่มีที่สิ้นสุดที่ตัดกันทรงกลมหากผู้แยกแยะเป็นบวก!!!!!!! (อันที่จริง การไม่เป็นเชิงลบถือเป็นเกณฑ์ความสนใจ) อ่านเอกสารที่คุณอ้างอิงถึงตัวเองและอ่านอย่างละเอียด   -  person    schedule 25.12.2011
comment
ถ้าเส้นตัดตัดทรงกลม เส้นถัดไปจะสามารถระบุได้ว่าจุดตัดนั้นอยู่ในทิศทางตามแนวรังสีที่รังสีนั้นชี้จริงหรือไม่   -  person    schedule 25.12.2011
comment
@woodchips ฉันดีใจมากที่คุณคิดว่าฉันคัดลอกคำจำกัดความลงไป และฉันได้อ่านเอกสารนี้แล้ว และไม่มีการกล่าวถึงบรรทัดใดในหน้านั้นเลย อย่างไรก็ตาม คำอธิบายของคุณดูสมเหตุสมผล เนื่องจากสามารถตรวจจับการชนทั้งสองด้านของรังสี (เช่น เส้น) เดาว่านั่นทำให้ฉันมีบางอย่างที่ต้องทำงานในตอนนี้ ขอบคุณ.   -  person user1115016    schedule 30.12.2011
comment
@woodchips แก้ไขแล้ว! การทดสอบเชิงลบอย่างง่ายสำหรับค่า t ได้ผล ขอบคุณอีกครั้งที่รักษาความวิกลจริตของฉัน   -  person user1115016    schedule 30.12.2011


คำตอบ (3)


คำตอบสั้น ๆ สำหรับปัญหาของฉัน ในกรณีที่มีคนพบสิ่งนี้และมีปัญหาเดียวกัน:

Discriminant จะบอกคุณว่ามี Hit สำหรับ line หรือไม่ (และ ไม่ใช่ สำหรับ ray อย่างที่ฉันคิด) หากเป็นบวก แสดงว่าตรวจพบการชนที่ไหนสักแห่งในเส้น

ดังนั้น เมื่อคำนวณค่า t ของรังสี ให้ตรวจสอบว่ามีค่าเป็นลบหรือไม่ หากเป็นเช่นนั้น มันจะเป็นการชนด้านหลังจุดกำเนิดของรังสี (เช่น ทิศทางตรงกันข้ามของรังสี) ดังนั้นให้ทิ้งมันไป เก็บเฉพาะค่าบวกเท่านั้น เนื่องจากพวกมันกระทบในทิศทางของรังสี

คำตอบที่สั้นกว่านี้อีก: ละทิ้งค่า t ที่เป็นลบ

ขอขอบคุณ woodchips ที่ทำให้ฉันตระหนักถึงสิ่งนี้

person user1115016    schedule 30.12.2011

ปัญหาคือ เคล็ดลับในการค้นหาจุดตัดของเส้นตรงและทรงกลมต้องใช้วิธีแก้สมการกำลังสอง สมการดังกล่าวมีความเป็นไปได้หนึ่งในสามของการแก้ปัญหา - สมการนั้นจะมีคำตอบจำนวนจริง 0, 1 หรือ 2 ข้อ สัญลักษณ์ของการเลือกปฏิบัติบอกเราว่ามีวิธีแก้ปัญหาที่แท้จริงจำนวนเท่าใด (รวมถึงการช่วยเราในการแก้ปัญหาเหล่านั้นด้วย)

หากมีวิธีแก้ปัญหาเฉพาะ เส้นก็จะลากไปแตะพื้นผิวของทรงกลม สิ่งนี้จะเกิดขึ้นเมื่อผู้จำแนกประเภทเป็นศูนย์ทุกประการ

หากมีวิธีแก้ปัญหาสองข้อ เส้นนั้นจะผ่านทรงกลมไปกระทบพื้นผิวในจุดที่แตกต่างกันสองจุด

หากไม่มีวิธีแก้ปัญหาที่แท้จริง (กรณีที่ผู้แยกแยะเป็นลบ) เส้นนั้นก็อยู่ห่างจากทรงกลมเกินกว่าจะสัมผัสได้เลย

เมื่อค้นพบว่าเส้นนี้เคยเข้าใกล้ทรงกลมหรือไม่ เราก็กังวลว่ารังสีจะกระทบทรงกลมหรือไม่ สำหรับสิ่งนี้ เรามาดูกันว่าเรานิยามรังสีอย่างไร รังสีเป็นเส้นครึ่งเส้นที่ขยายไปจนถึงอนันต์ในทิศทางเดียว เราจึงดูว่าจุดตัดเกิดขึ้นที่ใดบนเส้นตรง เฉพาะในกรณีที่จุดตัดเกิดขึ้นที่ครึ่งหนึ่งของเส้นที่เราสนใจเท่านั้น ถึงจะมีจุดตัดทรงกลมเรย์

ประเด็นก็คือ การคำนวณการแบ่งแยก (และทดสอบเครื่องหมายของมัน) จะบอกคุณเฉพาะเกี่ยวกับสิ่งที่เส้นนั้นทำ ไม่ใช่เกี่ยวกับจุดที่จุดตัดเกิดขึ้นตามเส้นนั้น

แน่นอนว่าการอ่านลิงก์ที่คุณให้มาอย่างละเอียดจะบอกคุณเรื่องทั้งหมดนี้ได้

person Community    schedule 25.12.2011
comment
คำตอบในความคิดเห็นของคุณมีประโยชน์มากกว่า - person user1115016; 30.12.2011

ค่อนข้างแน่ใจว่า "o-c" ควรจะเป็น "c-o"

คุณกำลังยิงรังสีออกไปผิดทิศทางและหาจุดตัดที่อีกด้านหนึ่งของทรงกลม

person Jeremiah    schedule 25.12.2011