[Closed] Curve (not straight line) – Plane intersection
Hi to everyone, I am doing a design project for which I need to compute all the points of N number of 3D vertical curves (but not straight ones), that intersect with a plane – the plane is on XY axis. I know there is a thread in cg forum for computational geometry issues, but unless I am mistaken, there isn’t any algorithm for this task right ? Any help, pointers, advices on this one ?
Thanks in advance.
I figured out this method but its not working properly. The getLinePlaneIntersect function returns a bunch of collinear points. If someone has time just evaluate the code below to see
what I mean.
I use the getLinePlaneIntersect function by IllusionCatalyst.
fn getLinePlaneIntersect &p3LinePoint_1 &p3LinePoint_2 &rPlane fEpsilon:1e-4 =
(
local p3LineVector = p3LinePoint_2 - p3LinePoint_1
local p3Vector_1 = rPlane.pos - p3LinePoint_1
local fNumer = dot rPlane.dir p3Vector_1
local fDenom = dot rPlane.dir p3LineVector
if ((abs fDenom) >= fEpsilon) then -- line intersects plane
return (p3LinePoint_1 + ((fNumer / fDenom) * p3LineVector))
else -- line is parallel to plane
return undefined
)
fn lineBetweenTwoPoints a b = (
spl = SplineShape()
addNewSpline spl
addKnot spl 1 #corner #line a
addKnot spl 1 #corner #line b
updateShape spl
spl.wirecolor = red
--spl
)
fn testShape = (
testShape = splineShape()
addnewSpline testShape
for i = 1 to 100 by 10 do
(
addknot testShape 1 #smooth #curve [i, (i*i / 100.0), i]
)
updateShape testShape
testShape.wirecolor = color 255 0 0
testShape
)
pl = plane pos:[0, 0, 50] width:100 length:100
r = Ray pl.pos pl.dir
testSh = testShape()
INTERP = 40
uStep = 1.0 / INTERP as float
previous = lengthInterp testSh 0
for u = uStep to 1.0 by uStep do (
current = lengthInterp testSh u
lineBetweenTwoPoints previous current
pt = getLinePlaneIntersect previous current r
if pt != undefined do point size:2.0 pos:pt wirecolor:green
previous = current
)
Ok, so there is indeed a question in the Geometric Computing thread about finding the intersection of a 3d spline and a plane. Didn’t see it before.
I kind of figured out a way of finding the exact point of intersection of a spline and a plane, but it will not work in all cases. That collinear points that I was talking about where actually the projections of each small line fragment that I build for the interpolation of the spline on the plane… So to elliminate those, for each small line fragment that I build, I first I check if the returned point from getLinePlaneIntersect fn, lies within the distance between the first and the second vertex of that line. Then I check if the point found is actually on the plane, since the getLinePlaneIntersect function will return a point of intersection even if that point is not physically on the plane (since it computes the intersection of a plane by taking its direction vector and translation vector which do not define its physical limits). Then since there might be 1 or two points that are really really close to each other (comment this line to see what I mean), I put a count variable that stops the for loop when the first point is found – but this will not do if we want two points of intersection.
It does the job for me although there should be other more mathematically oriented ways. You can try it out:
fn getLinePlaneIntersect &p3LinePoint_1 &p3LinePoint_2 &rPlane fEpsilon:1e-6 =
(
local p3LineVector = p3LinePoint_2 - p3LinePoint_1
local p3Vector_1 = rPlane.pos - p3LinePoint_1
local fNumer = dot rPlane.dir p3Vector_1
local fDenom = dot rPlane.dir p3LineVector
if ((abs fDenom) >= fEpsilon) then -- line intersects plane
return (p3LinePoint_1 + ((fNumer / fDenom) * p3LineVector))
else -- line is parallel to plane
return undefined
)
fn testShape = (
testShape = splineShape()
addnewSpline testShape
for i = 1 to 100 by 10 do
(
addknot testShape 1 #smooth #curve [i, (i * i /100), i ]
)
updateShape testShape
testShape.wirecolor = color 255 255 0
testShape
)
fn isPtWithinPlane pt pl = (
contains (box2 [pl.max.x, pl.max.y] [pl.min.x, pl.min.y]) [pt.x, pt.y]
)
pl = plane pos:[40, 0, 50] width:100 length:100
r = Ray pl.pos pl.dir
testSh = $
INTERP = 40
uStep = 1.0 / INTERP as float
previous = lengthInterp testSh 0.0
count = 0
for u = uStep to 1.0 by uStep while count < 1 do (
current = lengthInterp testSh u
pt = getLinePlaneIntersect previous current r
if pt != undefined then (
if distance previous pt <= distance previous current do (
if isPtWithinPlane pt pl do (
point size:4.0 box:on pos:pt wirecolor:green
count += 1
)
)
)
previous = current
)
Also I would appreaciate if someone could help write a better version that takes into consideration if two intersection points are needed. Cheers.