Code archives/3D Graphics - Maths/BMAX - Distance from Point to Line
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
This is some old C code i found and ported it to Bmax. basically the command to run is DistancePointLine it returns True or False if the Point is within the line's segment. but you can access its X Y & Z coordinates on the line by grabbing ix,iy,iz and Distance# is the area distance from the point to the line. | |||||
Function Magnitude#( px#,py#,pz#,dx#,dy#,dz# ) Local vx#,vy#,vz# vx# = dx# - px# vy# = dy# - py# vz# = dz# - pz# Return Float(Sqr( vx# * vx# + vy# * vy# + vz# * vz# )) End Function Function DistancePointLine( ax#,ay#,az#,bx#,by#,bz#,px#,py#,pz# ) Local LineMag#,U# Local ix#,iy#,iz# Local Distance# LineMag# = Magnitude( bx#, by#, bz#, ax#, ay#, az# ) U# = ( ( ( px# - ax# ) * ( bx# - ax# ) ) +( ( py# - ay# ) * ( by# - ay# ) ) +( ( pz# - az# ) * ( bz# - az# ) ) ) /( LineMag# * LineMag# ) If U# < 0.0 Or U# > 1.0 Then Return False ' closest point does Not fall within the line segment ix# = ax# + U# * ( bx# - ax# ) iy# = ay# + U# * ( by# - ay# ) iz# = az# + U# * ( bz# - az# ) Distance# = Magnitude( px#,py#,pz#,ix#,iy#,iz# ) Return True End Function |
Comments
| ||
a bit shorter and about 15% faster (using less locals each time the function is called)Function Magnitude#( px#,py#,pz#,dx#,dy#,dz# ) Return Float(Sqr( (dx# - px#)*(dx# - px#) + (dy# - py#)*(dy# - py#) + (dz# - pz#)*(dz# - pz#) )) End Function Function DistancePointLine( ax#,ay#,az#,bx#,by#,bz#,px#,py#,pz#, Distance# Var) Local LineMag#,U# Local ix# = bx# - ax# Local iy# = by# - ay# Local iz# = bz# - az# ' Local Distance# LineMag# = Magnitude( bx#, by#, bz#, ax#, ay#, az# ) U# = ( ( ( px# - ax# ) * ix# ) +( ( py# - ay# ) * iy# ) +( ( pz# - az# ) * iz# ) ) /( LineMag# * LineMag# ) If U# < 0.0 Or U# > 1.0 Then Return False ' closest point does Not fall within the line segment ix# = ax# + U# * ix# iy# = ay# + U# * iy# iz# = az# + U# * iz# Distance# = Magnitude( px#,py#,pz#,ix#,iy#,iz# ) Return True End Function Disabling the "Distance# var" and enabling the local again cuts the speed to 52/58 instead of 50/58. Using a^2 instead of a*a is instead a reason to be 300% as slow as the original code. bye MB |
| ||
MichaelB: Won't your Magnitude function be slightly slower, as you're calculating the vector components twice each? I almost always put calcs into locals if they're needed more than once, as Leon has done. It's easier to read, too. |
| ||
you may change it without big differences... but this avoids to declare 3 locals each call of "Magnitude". Magnitude is called twice times in "DistancePointLine". While the locals ix,iy and iz are declared in "DistancePointLine", I reused them to make the calculation of "U#" shorter and the final calculation of ix,iy and iz faster. That the original code is much easier to read is without comment... just wanted to make it a bit faster for the copy/paste-user who just wants to have the solution for a problem without learning something from it. bye MB |
Code Archives Forum