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

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

×