Jump to content
Alexey Vanzhula

Closest point to line

Recommended Posts

but isn't the catch here is point Q ?....how to get point Q out of the 'million' possible points...

 

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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?)

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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 :) )

  • Haha 1

Share this post


Link to post
Share on other sites

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 by pusat
  • Thanks 1

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites

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 1

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×