Code archives/3D Graphics - Maths/Ray intersect
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
Calculates the intersection between a triangle and a ray(vector) in 3d space. Similar idea to Elias_t's intersect DLL, but in blitz native code. Not sure of the speed difference between the two approaches. | |||||
; a vector type Type vector3D Field dx#,dy#,dz# End Type ; create a new vector object Function vector3D_Create.vector3D(x#,y#,z#) v.vector3d = New vector3d vector3d_set(v,x,y,z) Return v End Function ; set a vector object to a set of values Function vector3D_Set(v1.vector3d,x#,y#,z#) v1\dx# = x# v1\dy# = y# v1\dz# = z# End Function Const SAME_CLOCKNESS = 1 Const DIFF_CLOCKNESS = 0 Function vector3D_CheckSameClockDir(pt1.vector3d, pt2.vector3d,pt3.vector3d,norm.vector3d) ; calculate normal test.vector3d = vector3d_trinormal(pt1,pt2,pt3) dotprod# = test\dx*norm\dx + test\dy*norm\dy + test\dz*norm\dz Delete test If(dotprod < 0) Then Return DIFF_CLOCKNESS; Else Return SAME_CLOCKNESS; End If End Function ; calculate the normal of a triangle Function Vector3D_TriNormal.Vector3d(v1.Vector3d,v2.Vector3d,v3.Vector3d) ; calculate differences ux#= v3\dx#- v2\dx# uy#= v3\dy#- v2\dy# uz#= v3\dz#- v2\dz# vx#= v1\dx#- v2\dx# vy#= v1\dy#- v2\dy# vz#= v1\dz#- v2\dz# ; calculate vector n.Vector3D = vector3d_create((uy#*vz#)-(vy#*uz#),(uz#*vx#)-(vz#*ux#),(ux#*vy#)-(vx#*uy#)); New Vector3D mag# = Sqr#(n\dx#^2+n\dy#^2+n\dz#^2) ; create normal by scaling by 1/magnitude If mag#<>0 Then vector3d_set(n,n\dx#/mag#,n\dy#/mag#,n\dz#/mag#) Else vector3d_set(n,0,0,1) ; to remove and div 0 errors End If Return n End Function ; check if a ray from a given point intersects a triangle. ; Only considers an intersect if the triangle is 'facing' the point, ie. only intersects with the front of the triangle Function vector3d_LineTriIntersect(pt1.vector3d, pt2.vector3d, pt3.vector3d, linept.vector3d, vect.vector3d, pt_int.vector3d) ; vector form triangle pt1 To pt2 V1x# = pt2\dx - pt1\dx V1y# = pt2\dy - pt1\dy V1z# = pt2\dz - pt1\dz ; vector form triangle pt2 To pt3 V2x# = pt3\dx - pt2\dx V2y# = pt3\dy - pt2\dy V2z# = pt3\dz - pt2\dz ; vector normal of triangle norm.vector3d = vector3d_trinormal(pt1,pt2,pt3) ;vector3d_create(V1y*V2z-V1z*V2y,V1z*V2x-V1x*V2z,V1x*V2y-V1y*V2x) ; dot product of normal And Line's vector If zero Line is parallel To triangle dotprod# = norm\dx*vect\dx + norm\dy*vect\dy + norm\dz*vect\dz; If(dotprod < 0) ;Find point of intersect To triangle plane. ;find t To intersect point t1# = -(norm\dx*(linept\dx-pt1\dx)+norm\dy*(linept\dy-pt1\dy)+norm\dz*(linept\dz-pt1\dz)) t2# = (norm\dx*vect\dx+norm\dy*vect\dy+norm\dz*vect\dz) t#=t1/t2 ; If ds is neg Line started past triangle so can't hit triangle. If(t < 0) Then Delete norm:Return 0 vector3d_set(pt_int,linept\dx + vect\dx*t,linept\dy + vect\dy*t,linept\dz + vect\dz*t) If(vector3D_CheckSameClockDir(pt1, pt2, pt_int, norm) = SAME_CLOCKNESS) Then If(vector3D_CheckSameClockDir(pt2, pt3, pt_int, norm) = SAME_CLOCKNESS) Then If(vector3D_CheckSameClockDir(pt3, pt1, pt_int, norm) = SAME_CLOCKNESS) Then Delete norm Return 1; End If End If End If End If Delete norm Return 0 End Function ; example code below... function has not been heavily tested as yet p1.vector3d = vector3d_create(-1,1,-1) p2.vector3d = vector3d_create( 1,1,-1) p3.vector3d = vector3d_create( 0,1, 1) linept.vector3d = vector3d_create(0,0,0) vect.vector3d = vector3d_create(0,10,1) pt_int.vector3d = vector3d_create(0,0,0) ci = vector3d_LineTriIntersect(p1,p2,p3,linept,vect,pt_int) If ci Then DebugLog "Intersected at x:"+pt_int\dx+" y:"+pt_int\dy+" z:"+pt_int\dz Else DebugLog "Does not intersect" End If DebugLog "---------------------------------------------" vector3d_set(vect,0,10,20) ci = vector3d_LineTriIntersect(p1,p2,p3,linept,vect,pt_int) If ci Then DebugLog "Intersected at x:"+pt_int\dx+" y:"+pt_int\dy+" z:"+pt_int\dz Else DebugLog "Does not intersect" End If While Not KeyDown(1) Wend Delete Each vector3d End |
Comments
None.
Code Archives Forum