Intersection coordinates between line and spline fitted curve

Hello,
I am trying to do a similar thing to the request posted here: Intersection of a spline fitted curve and a straight line

The difference is that I would like to do it by getting the coordinates of the point on the curve common to the straight line to get the intersection (I thought about a “for” loop). So far, I have the equation parameters of the straight line and the x and y coordinates of the curve but don’t know how to find their common coordinates…

Any idea?

How is that different from the solution suggested by @Kota in mentioned thread? In macro language, you’d do Roi.getCoordinates(xpoints, ypoints) to obtain the intersection location. Near this link there are more commands to interact with ROIs and RoiManager…
This question on creating a segmented line with marks also has a few interesting aspects, such as getting intermediate coordinates of a spline curve.

Hi,

here’s a solution in python. It does the following

  • gets the equation of the line
  • interpolates the spline with a given stepsize. This determines accuracy of the solution
  • It calculates how far each interpolated point is from being on the line
  • finds the points on the spline with the stepsize of the line

Here’s the code and some screenshots

Cheers,

Chris

1 solution

0 solutions

4 solutions

from ij import IJ
imp = IJ.getImage()

# get the roi manager 
from ij.plugin.frame import RoiManager
roim = RoiManager.getInstance()

# I'm storing the spline roi first and the line second
spline = roim.getRoi(0)
line    = roim.getRoi(1)

# get the points of 
x0,x1=line.getPolygon().xpoints
y0,y1=line.getPolygon().ypoints

# get finely spaced points from the spline 
# the smaller you make the step the more accurate the intersection
ds=0.2
poly = spline.getInterpolatedPolygon(-ds,True)
xpoints = poly.xpoints
ypoints = poly.ypoints

def deviaton_from_line( x,y, x0,y0, x1,y1):
	from math import sqrt
	# if x,y are on line formed by (x1,y0) and (x1,y1)
	# this returns 0
	# see https://en.wikipedia.org/wiki/Line_(geometry)#On_the_Cartesian_plane
	# and https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
	a = (y1-y0)
	b = (x1-x0)
	return abs(a*(x-x0)-b*(y-y0))/sqrt(a*a+b*b)

# calculate the deviation for the points in the line
dev = [ deviaton_from_line(x,y, x0,y0, x1,y1)  for x,y in zip(xpoints,ypoints) ]

# find maximun with the stepsize
from ij.plugin.filter import MaximumFinder
indx = MaximumFinder.findMinima(dev, ds,False)

# keep solutions less tha 2*the stepsize
sols_x = [ xpoints[i] for i in indx if dev[i]<2*ds  ]
sols_y = [ ypoints[i] for i in indx if dev[i]<2*ds  ]

# plot the points
from ij.gui import PointRoi
point = PointRoi( sols_x, sols_y )
imp.setRoi( point)
2 Likes

Thanks for the suggestions eljonco. The reason why I wanted a “geometrical” method is to gain more accuracy.

Thank you evenhuis. This is the kind of solution I am after. I unfortunately don’t know the Python language but I will try to port this script to IJ1 in the macro that I started and let you know how it goes.
This was very useful!

1 Like

Hi Olivier,
Did you succeed to port it to an IJ macro script?
If so could you share it with the forum?

Thanks in Advance,
Peter

Here you go

// I'm storing the spline roi first and the line second
roiManager("select",1);
getSelectionCoordinates(xline, yline);
x0 = xline[0]; x1=xline[1];
y0 = yline[0]; y1=yline[1];



// get finely spaced points from the spline 
// the smaller you make the step the more accurate the intersection
ds=0.2;
roiManager("select",0);
run("Interpolate", "interval="+ds+" adjust");
getSelectionCoordinates(xpoints, ypoints);

function deviaton_from_line( x,y, x0,y0, x1,y1){
	// if x,y are on line formed by (x1,y0) and (x1,y1)
	// this returns 0
	// see https://en.wikipedia.org/wiki/Line_(geometry)#On_the_Cartesian_plane
	// and https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
	a = (y1-y0);
	b = (x1-x0);
	return abs(a*(x-x0)-b*(y-y0))/sqrt(a*a+b*b);
}
// calculate the deviation for the points in the line
dev = newArray(xpoints.length);
for(i=0;i<xpoints.length;i++){
	dev[i] = deviaton_from_line(xpoints[i],ypoints[i], x0,y0, x1,y1);
}


indx = Array.findMinima(dev, ds);

// keep solutions less tha 2*the stepsize
nsols=0;
sols_x = newArray(indx.length);
sols_y = newArray(indx.length);
for( i=0; i<indx.length; i++ ){
	ind = indx[i];
	if( dev[ind]<2*ds ){
		sols_x[nsols]=xpoints[ind];
		sols_y[nsols]=ypoints[ind];
		nsols++;
	}
}
sols_x=Array.trim(sols_x,nsols);
sols_y=Array.trim(sols_y,nsols);

makeSelection("point", sols_x, sols_y);

Thanks for posting it @evenhuis. I must admit that I was stuck after the deviation step.