Alexey Vanzhula Posted January 17, 2018 Share Posted January 17, 2018 Hi. I want to find closest point to line. Geometry has millions of points and the line is located somewhere in space. Need some fast solution. image Quote Link to comment Share on other sites More sharing options...
ikoon Posted January 17, 2018 Share Posted January 17, 2018 Hi Alexey, maybe this? https://www.sidefx.com/docs/houdini/vex/functions/ptlined.html 1 Quote Link to comment Share on other sites More sharing options...
Noobini Posted January 17, 2018 Share Posted January 17, 2018 but isn't the catch here is point Q ?....how to get point Q out of the 'million' possible points... Quote Link to comment Share on other sites More sharing options...
Noobini Posted January 17, 2018 Share Posted January 17, 2018 just testing...no idea how to VEXify...(pretty fast for ~3mil points pighead) ClosestPtLine.hipnc 1 Quote Link to comment Share on other sites More sharing options...
Noobini Posted January 18, 2018 Share Posted January 18, 2018 (edited) my feeble attempt at VEX...won't win any speed contest... ClosestPtLineWrangle.hipnc Edited January 18, 2018 by Noobini 1 Quote Link to comment Share on other sites More sharing options...
Alexey Vanzhula Posted January 18, 2018 Author Share Posted January 18, 2018 Thanks guys! Noobini, the line is really infinite. Sorry for wrong image. Currently I walk through all points with ptlined in wrangle SOP (detail mode). It works well but not so fast as I want. Still experimenting. Quote Link to comment Share on other sites More sharing options...
ikoon Posted January 18, 2018 Share Posted January 18, 2018 Hi Alexey, I am no master at optimization, but you may divide it into more steps: - point wrangle to store @distance (so it uses all the cpu cores) - sort by attribute (compilable, so maybe it can use all the cores?) Quote Link to comment Share on other sites More sharing options...
Alexey Vanzhula Posted January 18, 2018 Author Share Posted January 18, 2018 Just now, ikoon said: Hi Alexey, I am no master at optimization, but you may divide it into more steps: - point wrangle to store @distance (so it uses all the cpu cores) - sort by attribute (compilable, so maybe it can use all the cores?) I also think about this. I'll try it Quote Link to comment Share on other sites More sharing options...
Noobini Posted January 18, 2018 Share Posted January 18, 2018 15 minutes ago, Alexey Vanzhula said: Thanks guys! Noobini, the line is really infinite. Sorry for wrong image. Currently I walk through all points with ptlined in wrangle SOP (detail mode). It works well but not so fast as I want. Still experimenting. haha...no worries...there's just a slight difference between something....and something infinite.....(small technical details ) 1 Quote Link to comment Share on other sites More sharing options...
Alexey Vanzhula Posted January 18, 2018 Author Share Posted January 18, 2018 4 hours ago, ikoon said: compilable, so maybe it can use all the cores? Compiled block will use all the cores only when you wrap foreach block with it Quote Link to comment Share on other sites More sharing options...
animatrix Posted January 18, 2018 Share Posted January 18, 2018 (edited) ptlined will be slow because it's calling sqrt(). You should implement your own pointLineDistanceSquared: vector pointLineDistanceSquared ( vector p; vector linep0; vector linep1 ) { vector dir = linep1 - linep0; vector pp = p - linep0; return length2 ( cross ( dir, p ) ) / length2 ( dir ); } Then you can multi-thread the distance calculation using Run Over Numbers, storing them as detail attributes and then compute the smallest one at the last step. Edited January 19, 2018 by pusat 1 Quote Link to comment Share on other sites More sharing options...
Alexey Vanzhula Posted January 18, 2018 Author Share Posted January 18, 2018 27 minutes ago, pusat said: ptlined will be slow because it's calling sqrt(). You should implement your own pointLineDistanceSquared: vector pointLineDistanceSquared ( vector p; vector linep0; vector linep1 ) { vector dir = linep1 - linep0; vector pp = p - linep0; return length2 ( cross ( dir, p ) ) / length ( dir ); } Then you can multi-thread the distance calculation using Run Over Numbers, storing them as detail attributes and then compute the smallest one at the last step. Very interesting. I never used Run Over Numbers. Can you create example scene, please? Quote Link to comment Share on other sites More sharing options...
fathom Posted January 20, 2018 Share Posted January 20, 2018 distance to an infinite line is really a 2d distance that's been rotated out of alignment to a cardinal axis. so imagine rather than an arbitrary line, you were trying to find the point closest to the y axis. it would be the point with the least value of (x*x+z*z). trivial. so now you just need to transform everything such that your infinite line is the y-axis. because we only care about distance, we can do this very easily with a shear transform -- adding a proportion of the y value to each of x and z. the proportions for each is based on the slope of your original line. the math would be something like this (drycoding here... don't have houdini available atm): > // p0 and p1 are the points of your line float x = P.x - p0.x - P.y*(p1.x-p0.x)/(p1.y-p0.y); float z = P.z - p0.z - P.y*(p1.z-p0.z)/(p1.y-p0.y); f@distanceSquared = x*x+z*z; if p1.t-p0.y is too small (like abs() less than 0.0001 or something), you should select a different cardinal axis. 1 Quote Link to comment Share on other sites More sharing options...
Alexey Vanzhula Posted January 21, 2018 Author Share Posted January 21, 2018 12 hours ago, fathom said: distance to an infinite line is really a 2d distance that's been rotated out of alignment to a cardinal axis. so imagine rather than an arbitrary line, you were trying to find the point closest to the y axis. it would be the point with the least value of (x*x+z*z). trivial. so now you just need to transform everything such that your infinite line is the y-axis. because we only care about distance, we can do this very easily with a shear transform -- adding a proportion of the y value to each of x and z. the proportions for each is based on the slope of your original line. the math would be something like this (drycoding here... don't have houdini available atm): > // p0 and p1 are the points of your line float x = P.x - p0.x - P.y*(p1.x-p0.x)/(p1.y-p0.y); float z = P.z - p0.z - P.y*(p1.z-p0.z)/(p1.y-p0.y); f@distanceSquared = x*x+z*z; if p1.t-p0.y is too small (like abs() less than 0.0001 or something), you should select a different cardinal axis. Thanks, I'll try it. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.