# Line segment intersecting curve

This topic is 3660 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello guys, I'm searching for algorithm such as : Line vs Bezier curve intersection test... And didn't find anything... Here is picture : So the normal depends on Line Segment direction, it will be pointed to line seg beginning, point A. So the normal is a unit vector like (0,1) or (0.5,0.5) it show as a perpendicular to intersection surface... I know that there can be many intersection points, but we pick that point which closer to point A of line segment... I'm not so smart in High mathematics, and cubical equations, and tangent equations, so help me please.. [Edited by - Lolmen on December 5, 2007 8:44:27 PM]

##### Share on other sites
I'd start by getting everything relative to point A on the line. Then you can get an equation for your line something like mx+ny=0 where m = -By and n = Bx (that's B relative to A). Then you can substitute your bezier formulas (also relative to A)into the x and y in that equation, and get a new 1 dimensional cubic equation where the roots give the t values of the original bezier curve where it collides with that point. I'm not going to explain how to find the roots of a cubic equation because there's plenty of information online that explains it better than I could. Once you have the t values (there could be up to 3) you can substitute those back into your original bezier curve and check which point is the closest to A(that would be your M) . Once you have the closest t value you can put that into the derivative of your bezier curve to get the tangent vector at the point(T). There is a more complex definition of the normal to a curve, but it looks like you just want a normalized vector perpendicular to the curve facing a certain direction. So I'd suggest you use N=(-Ty,Tx) then if ( N.(A-M) <0) multiply N by -1, and of course finish up by dividing N by it's length.

P.S. The magnitude of (0.5,0.5) is sqrt(2)/2

##### Share on other sites
I almost don't get anything, because As I say, High mathematic teh suck, and I can't clearly understand the concept.
Well I can undertand you, if you show it to me step by step with real samples, wow, forget one thing, for solve cubical equations in inet we can search for SolveCubic code... This can help us somehow...
But the rest part I strongly suggest show me how it works, like solve step by step without skipping some curve here, hence theorys without practical samples don't give me anything usable. :)

Somebody notice that best approx approach is react this intersection by using nishita Bezier clipping, but I don't find anything really good paper...

[Edited by - Lolmen on December 3, 2007 12:35:49 PM]

##### Share on other sites
I have found that paper using google.

##### Share on other sites
Hah, that's exacly what I'm read before, but as I said, I'm not so smart in Mathematics... So if you can understand the concept, try to figure out some code...

##### Share on other sites
I'm afraid I can't help in figuring out how to compute it, but I feel I should point out that an arbitrary line intersection with an arbitrary bezier COULD result in multiple intersections; two for a 3-point bezier (quadratic?) and three for a 4-point cubic bezier (twisted into a pretzel shape).

This may not be an issue for you if you know that your curves and lines fall within certain ranges where this won't happen.

##### Share on other sites
I appreciate any working algorithm, to figure out how to be with multiple intersection pts we can just sorth them, to pick closest point to beginning of a line segment, so if you can help, try it.

##### Share on other sites
The idea behind the algorithm presented in that paper is to define a new Bézier curve that represent the distance between the original Bézier curve and the line.

1. The first things to do is to write the equation of the line in implicit form. Given A(ax, ay), B(bx, by) and the vector d(dx, dy)=normalize(B-A) the equation is
dyx - dxy + C = 0
where C = aydx - axdy

2. The distance between a point and the line is defined by the following function:
dist(x,y) = dyx - dxy + C

2. The Bézier curve that describe the distance between the line and the points in the original Bézier curve is the following:
D(t) = (1-t)3dist(P0) + 3t(1-t)2dist(P1) + 3t2(1-t)dist(P2) + t3dist(P3)

3. You have at this point two possibilities: solve the cubic equation D(t) = 0 or use an approximated method like the one described in the paper. What method do you prefer?

P.S. I suggest to improve your math knowledge. You will probably find in the future harder problems to solve.

Edit:
The normal of a curve is traditionally described by the tangent vector rotated by 90°. But if you aren’t able to calculate the tangent vector it isn’t very useful. I’m currently unable to find a formula and I want to go to sleep.

[Edited by - apatriarca on December 3, 2007 5:22:06 PM]

##### Share on other sites
I think pick method from this paper, if every body taliking about this Nishita'sh approach as first for real time graphics, so it should be faster than solve cubical equaton...

I understand the first thing...

But I'm not sure about thing №2...

[Edited by - Lolmen on December 5, 2007 8:59:51 PM]

##### Share on other sites
What I have written is only math not code.
The first part of the equation of the line (dyx - dxy + C) is the formula (that I have called dist(x,y) in the 2) to find the distance between the line and the point (x, y). The points with the distance equals to zero are the points the lie on the line. The function described in 3 is a function that given the parameter t of a point on the Bézier curve returns it’s distance to the line.
How much do you know about Bézier curve?

##### Share on other sites
I know how to draw it :) And some theory and stuff, but no math...
So code, yep, I'm understand math more clearly when I look at code, so the way for me is understand how it works is transform to code, and then read it, but problem is that I'm not so quite to solve equations like Z = ax+bx+cx+d or something like that...

I can solve solution like ax+b=0

equation sample : kx+b=0 two components should be known
solution for x if known k and b
kx=0-b
x=(-b/k)
solution for k if known x and b
k = b/x
solution for b if known x and k
b = 0-kx

I try to figure out something for ax+bx+c=0
like place bx+c=0 as t then solve ax+t=0
but no luck...
But it's just equations, what the deal with vector here? What we searching by line equation ax+bx+c=0 where we get "C" and so on?

[Edited by - Lolmen on December 3, 2007 8:27:24 PM]

##### Share on other sites
The equation of the line has two unknown: x and y.
The equation you have written (ax+bx+c=0) has one unknown (x) and the solution is -c/(a+b).
The equation of the line has infinite solutions (all the coordinates of the points in the line are solutions of the equation).
But in this case you don’t need to solve the equation. You have to use the first part of the equation to calculate the distance from the line to a given point (for example the first control point).

Have you ever listened about the de Casteljau algorithm? Do you know how to subdivide a bézier curve in two or more bézier curve? Do you know what the Convex Hull is?

My fear is that if I give you the code you will probably use it without any understanding.

##### Share on other sites
>Have you ever listened about the de Casteljau algorithm?
Nope...
>Do you know how to subdivide a bézier curve in two or more bézier curve?

I know that solution can be found without subdivisions, recursion will be costly thing...

>Do you know what the Convex Hull is?
Well, cheap is AABB, but best is OBB, using polygons bad idea.

Do Bezier clipping use one of these two first algorithms?

##### Share on other sites
Bézier clipping is a recursive algorithm that involve the subdivision of the Bézier curve.

You have to find the intersection between the convex hull and the y=0 line. If you call t0 and t1 the first and the last intersection, you subdivide the Bézier curve in 3 parts: the part with the parameter less than t0, the part with parameter between t0 and t1 and the last part of the Bézier curve. You then do the same things with the second part until t1-t0 is less than a given number.

##### Share on other sites
y=0 line?
Given number?

Can you show me code for that?

##### Share on other sites
The “given number” is the error that you think is acceptable in your implementation. The Bézier clipping give an approximated solution. With every iteration you get a better approximation but there will always be some error. The algorithm stop to recurse when the error is lower than what you have decided.

The convex hull of the bézier curve is the smaller polygon that contains the control points. The bézier curve is always contained in that polygon and, if the segment doesn’t intersect with the convex hull it doesn’t intersect with the curve.

You have to consider the 1D bézier curve with the control “points” dist(P0), dist(P1), dist(P2), dist(P3) where dist is the formula previously described where you substitute x and y with the coordinates of the point passed as the parameter.
In code is something like this:
float dist(Vector &d, float c, Point &p){    return d.y*p.x + d.x*p.y + c;}

This curve gives you the distance of a point on the bézier curve to the line that contains the segment. Calculating the intersection between the original curve and the line become the problem to find all the values of t that, inserted in the formula of this 1D bézier curve, gives a value equals to zero.

The bézier clipping algorithm works in the following way:
* Calculate the convex hull of the curve (the 1D curve...)
* Find where the convex hull cross the x-axis (t0 is the lower value and t1 is the higher)
* If t1-t0 is bigger than 0.8 subdivide in half the curve and recurse for each half and return the two intersections founded.
* If t1-t0 is lower than the maximum error acceptable than return (t0+t1)/2
* Subdivide the curve in three parts (“cut” the curve at the points t0 and t1)
* Recurse passing as parameter the part of the curve defined inside the interval [t0,t1]

##### Share on other sites
I'm currently can't imagine 1D curve :D
So I'm post up some code later, check out below:

[Edited by - Lolmen on December 5, 2007 8:19:16 PM]

##### Share on other sites
Ok, It takes too long time, I can't waste too much time, I have to make my game...

So can you show me formulas to compute A,B,C coefficients for cubic equation solver from given line segment start, end and Curves Px?
And also check do I compute roots right:

// Bezier: (1-t)^3 * P0 + 3t(1-t)^2 * P1 + 3t^2 * (1-t)P2 + t^3 * P3, t -> [0, 1]inline Vector B( float t, Vector P1, Vector P2, Vector P3, Vector P4 ){	t = clamp( t, 0.0f, 1.0f ); // make sure t doesn't grows up	return CUBE(1.0f-t)*P1 + 3.0f*t*SQUARE(1.0f-t) * P2 + 3.0f*SQUARE(t)*(1.0f-t)*P3 + CUBE(t)* P4;}// Intersetion function// returns: t -> [0, 1] parameter and segment intersection point in M.// if function returns false, so there is no intersections;inline bool Intersection(BezierCurvePoints & bCurve, Vector vSrc, Vector vEnd, Vector& M, float t){        double A,B,C; // TODO : compute them out use bCurve.Px and vSrc, vEnd	double results[3]; // maximum roots        // resturns roots quantity and fill results array	int roots = SolveCubic(results, a, b, c);	if ( roots != 2 ) // roots < 2 && roots > 2	{                // first root is less than 0 or bigger than 1		if ( results[0] < 0 || results[0] > 1 )			return false;				// Try findout inerestion point for first root		M = B( results[0], bCurve.P0, bCurve.P1, bCurve.P2, bCurve.P3 );                // check do out segment intersect given point on curve		if ( IsLineSegmentIntersectPoint( vSrc, vEnd, M ) )                {                        t = results[0];			return true; // point match                }                 // otherwise point not match		return false;	}	Vector temp;        // checking for bad root numer one and two	bool badRoot1 = results[1] < 0 || results[1] > 1;	bool badRoot2 = results[2] < 0 || results[2] > 1;                if ( badRoot1 && badRoot2 )	    return false;	if (badRoot1)	{                // put root 1 to bezier function		M = B( results[1], bCurve.P0, bCurve.P1, bCurve.P2, bCurve.P3 );		if ( IsLineSegmentIntersectPoint( vSrc, vEnd, M ) )                {			t = results[1];                        return true;                }		return false;	}	else if (badRoot2)	{		M = B( results[2], bCurve.P0, bCurve.P1, bCurve.P2, bCurve.P3 );		if (IsLineSegmentIntersectPoint( vSrc, vEnd, M ) )                {			t = results[2];                        return true;                }		return false;	}	else	{                // we probably have two intersection points, find closest?                // try find out match root		Vector M1 = B( results[1], bCurve.P0, bCurve.P1, bCurve.P2, bCurve.P3 );		Vector M2 = B( results[2], bCurve.P0, bCurve.P1, bCurve.P2, bCurve.P3 );				int root = 0;				Vector d1 = vSrc - M1;		Vector d2 = vSrc - M2;                // compare vector lengths		if ( d1.Length() >= d2.Length() ){ M = M1; root = 1; }		if ( IsLineSegmentIntersectPoint( vSrc, vEnd, M ) )                        t = results[root];			return true;		return false;	}}

I write this code here, so I can't know how much it correct.
Because of these hard mathematics, which mush up my mind...

##### Share on other sites
A cubic bézier curve written as a cubic polynomial is
(P3 - 3P2 + 3P1 - P0)t3 + 3(P2 - 2P1 + P0)t2 + 3(P1 - P0)t + P0
where P0, P1, P2, P3 are the control point of the bézier curve.

If you divide everything by the coefficient of t3 you obtain the following polynomial
t3 + at2 + bt + c
where
a = 3(P2 - 2P1 + P0)/(P3 - 3P2 + 3P1 - P0)
b = 3(P1 - P0)/(P3 - 3P2 + 3P1 - P0)
c = P0/(P3 - 3P2 + 3P1 - P0)

The 1D bézier “curve” that I have presented before is a function that, given a value for t as argument, returns a value (the distance between the line and a point in the original bézier curve). It’s very similar to the curve in 2D but it returns a single float value instead of a 2D point (a point in a line has a single coordinate). The points of intersections are those points that have a distance from the line equals to zero.

[Edited by - apatriarca on December 5, 2007 2:53:49 PM]

##### Share on other sites
Here is some code.
float dist(const Vector &d, float c, const Point &p){    return d.y*p.x + d.x*p.y + c;}bool intersection(const Point &A, const Point &B, const BezierCurve &bez){    Vector d = normalize(B-A);    float c = A.y*d.x - A.x*d.y;	    float D0 = dist(d, c, bez.P0);    float D1 = dist(d, c, bez.P1);    float D2 = dist(d, c, bez.P2);    float D3 = dist(d, c, bez.P3);    float s = 1.0f/(D3 - 3.0f*D2 + 3.0f*D1 - D0);    float c0 = 3.0f*(D2 - 2.0f*D1 + D0)*s;    float c1 = 3.0f*(D1 - D0)*s;    float c2 = D0*s;    float t0, t1, t2;    unsigned roots;    // I suppose solveCubic is a function that finds the roots of x^3 + c0*x^2 + c1*x + c2    // returns the number of roots    roots = solveCubic(c0, c1, c2, &t0, &t1, &t2);    // you have now to see if the intersections are in the interval [0,1] and if the points    // are in the segment}

I haven’t tested or compiled the code.

[Edited by - apatriarca on December 6, 2007 2:18:15 PM]

##### Share on other sites
Ok I figure out code, but as result, seems to be something not work, maybe I'm mistaken somewhere, I tried to find out mistake about 2 hours, and didn't find it. The result is that you get intersection point if you are very lucky, yeah it lying on curve, but it occurs when line segment even not touch curve itself, and at some cases in intersection points can be results such as 0,0 which is worng, and 1.#QNANO or something like that...

May you take a look (test/check) it, and point me what I sholud fix, or what I forgot?

Here you go:
#define LINE_EPSILON (1.0E-8)#define SQUARE( x )( (x) * (x) )#define CUBE( x )( (x) * (x) * (x) )// cubic equation: x^3 + ax^2 + bx + c = 0;inline int SolveCubic(double * x, double a, double b, double c){        #define ONE_BY_3 0.33333333333333333333333333333333 // 1/3        #define HALF_SQRT3 0.866025403784438765 // sqrt(3.0) * 0.5	double q, r, r2, q3;        double sq_a = SQUARE(a);	q = (sq_a - 3.0 * b) / 9.;	r = (a * (2.0 * sq_a - 9.0 * b) + 27.0 * c) / 54.0;	r2 = SQUARE(r);	q3 = CUBE(q);	if (r2 < q3)	{		double t = acos(r / sqrt(q3));		a /= 3.0;		q = -2.0 * sqrt(q);		x[0] = q * cos(t / 3.0) - a;		x[1] = q * cos((t + M_2PI) / 3.0) - a;		x[2] = q * cos((t - M_2PI) / 3.0) - a;		return 3;	}	else	{		double aa, bb;		if ( r <= 0.0 ) r = -r;		aa = -pow( r + sqrt(r2 - q3), ONE_BY_3 ); 		if ( abs(aa) < LINE_EPSILON ){ bb = q / aa; }		else { bb = 0.0; }		a /= 3.0;		q = aa + bb;		r = aa - bb; 		x[0] = q - a;		x[1] = (-0.5) * q - a;		x[2] = HALF_SQRT3 * fabs(r);		if( fabsf( x[2] ) < LINE_EPSILON ) return 2;		return 1;	}}// Bezier: (1-t)^3 * P0 + 3t(1-t)^2 * P1 + 3t^2 * (1-t)P2 + t^3 * P3, t -> [0, 1]inline Vector B ( float t, Vector P1, Vector P2, Vector P3, Vector P4 ){	t = clamp( t, 0.0f, 1.0f );	return CUBE(1.0f-t)*P1 + 3.0f*t*SQUARE(1.0f-t) * P2 + 3.0f*SQUARE(t)*(1.0f-t)*P3 + CUBE(t)* P4;} // working because also used for drawning curve!float dist(const Vector &d, float c, const Vector &p){	return d.y*p.x + d.x*p.y + c;}//--------------------------------------------------------------------// Line equation M = vSrc*(1.0-t) + vEnd*t;//--------------------------------------------------------------------inline bool IsLineSegmentIntersectPoint( Vector vSrc, Vector vEnd, Vector M ){	float u = 0.0f;	if ( fabsf(vEnd.x - vSrc.x) < LINE_EPSILON ) 	{ u = (M.y - vSrc.y)/(vEnd.y - vSrc.y); } 	else { u = (M.x - vSrc.x)/(vEnd.x - vSrc.x); }	if ( u < 0.0f || u > 1.0f ) { return false; } // the point isn’t in the segment	return true;}bool IsLineSegmentIntersectCurve( BezierCurvePoints bCurve, Vector vSrc, Vector vEnd, Vector &M, float &t ){	Vector N = (vEnd-vSrc).Normal();	float c = vSrc.y*vEnd.x - vSrc.x*vEnd.y;	// I also try float c = vSrc.y*N.x - vSrc.x*N.y; 	// but seems to be both is wrong, because you not explain what is this D?	float D0 = dist(N, c, bCurve.P0);	float D1 = dist(N, c, bCurve.P1);	float D2 = dist(N, c, bCurve.P2);	float D3 = dist(N, c, bCurve.P3);	float c0 = 3.0f*(D2 - 2.0f*D1 + D0)/(D3 - 3.0f*D2 + 3.0f*D1 - D0);	float c1 = 3.0f*(D1 - D0)/(D3 - 3.0f*D2 + 3.0f*D1 - D0);	float c2 = D0/(D3 - 3.0f*D2 + 3.0f*D1 - D0);	double results[3]; // array with taken results	int roots = SolveCubic(results, c0, c1, c2);	// local definition	#define IS_BAD_ROOT( x )	( (x) < 0.0f || (x) > 1.0f )		// Search for roots in interval t -> [0,1]	// And if so, then check that point on curve is belonging to line segment	bool bIntersectionFound = false;	switch( roots ) // switch roots quantity to process it	{	case 1:		{			if ( IS_BAD_ROOT( results[0] ) ) 			{ bIntersectionFound = false; }			else			{				M = B( results[0], bCurve.P0, bCurve.P1, bCurve.P2, bCurve.P3 );				if ( IsLineSegmentIntersectPoint(vSrc, vEnd, M) )				{					t = results[0];					bIntersectionFound = true;				}			}		} break;	case 2:		{			bool bRoot1IsBad = IS_BAD_ROOT( results[0] );			bool bRoot2IsBad = IS_BAD_ROOT( results[1] );			if ( (bRoot1IsBad && bRoot2IsBad ) != true )			{				bIntersectionFound = true;				if ( !bRoot1IsBad )				{					M = B( results[0], bCurve.P0, bCurve.P1, bCurve.P2, bCurve.P3 );					if ( IsLineSegmentIntersectPoint(vSrc, vEnd, M) )					{						t = results[0];					}					else					{						bIntersectionFound = false;					}				}				else				{					M = B( results[1], bCurve.P0, bCurve.P1, bCurve.P2, bCurve.P3 );					if ( IsLineSegmentIntersectPoint(vSrc, vEnd, M) )					{						t = results[1];					}					else					{						bIntersectionFound = false;					}				}			}		} break;	case 3:		{			bool bRoot1IsBad = IS_BAD_ROOT( results[0] );			bool bRoot2IsBad = IS_BAD_ROOT( results[1] );			bool bRoot3IsBad = IS_BAD_ROOT( results[2] );			if ( (bRoot1IsBad && bRoot2IsBad && bRoot3IsBad) != true )			{				bIntersectionFound = true;				if ( !bRoot1IsBad )				{					M = B( results[0], bCurve.P0, bCurve.P1, bCurve.P2, bCurve.P3 );					if ( IsLineSegmentIntersectPoint(vSrc, vEnd, M) )					{						t = results[0];					}				}				else				{					if ( !bRoot2IsBad )					{						M = B( results[1], bCurve.P0, bCurve.P1, bCurve.P2, bCurve.P3 );						if ( IsLineSegmentIntersectPoint(vSrc, vEnd, M) ){ t = results[1]; }					}					else					{						M = B( results[2], bCurve.P0, bCurve.P1, bCurve.P2, bCurve.P3 );						if ( IsLineSegmentIntersectPoint(vSrc, vEnd, M) ){ t = results[2]; }					}				}			}		} break;	default: 		break;	}	// This is for debug information	if ( bIntersectionFound )	{		char * buffer = new char[24];		sprintf(buffer, "s1:%f s2:%f s3:%f rq:%d\n", results[0],results[1],results[2], roots);		MessageBoxA(0, buffer, "Test", MB_OK);		delete []buffer;	}		return bIntersectionFound;}

[Edited by - Lolmen on December 6, 2007 9:49:42 AM]

##### Share on other sites
The defines are always global. The preprocessor doesn’t know anything about functions or local scope or namespace.
The only way to define a macro that exixts only in a part of the file is to undef the macro after it’s use. For example:
#define MACRO// code that use MACRO#undef MACRO

Your definition for the macro is more complicated than it should be.
First of all you don’t need the epsilon in this case. Second you can directly returns the value of the expression before the ?. That expression is in fact a boolean expression and is evaluated as a bool.
// local definition#define IS_BAD_ROOT( x ) ((x)<0.0f || (x)>1.0f))

The intersection point that you have found is inside the line. If T is the point of intersection you have the following vector equation to solve (the only unknown is u):
A + u(B-A) = T
u(B-A) = T - A
u = (T-A)/(B-A)
where the / is a per-component divide.
You only need to solve this equation for one of the component. You can for example do that for the x-component. If (B.x-A.x) is near zero than the line is near vertical and is better to use the y-component.
In code is something like the following:
// The parameter in the segment equation is returned in the last argumentbool pointInLineInSegment(const Point &A, const Point &B, const Point &T,     float &u){    if (abs(B.x - A.x) < LINE_EPSILON) {        u = (T.y - A.y)/(B.y - A.y);    } else {        u = (T.x - A.x)/(B.x - A.x);    }    return u >= 0.0f && u <= 1.0f;}

I have only read a part of your code but I have to go to lesson. I will continue later. I have corrected some typo error and modified some line of the code. Control if the error in your code is due to one of the errors I have corrected.

Edit: I have eliminated the useless if

[Edited by - apatriarca on December 6, 2007 11:36:13 AM]

##### Share on other sites
Well, this : expression ? true : false

:D yep, it's my crazy mania to make code more precise, to have more chances to see results, and not in all cases it will be good :)

But this is just a cosmetics typos, it even not wreck the code... :)

You have it too, example in point equation :

// other code
if (u < 0.0f || u > 1.0f) { return false; }
else { return true; }
// exit funtion

And we can just use :
if (u < 0.0f || u > 1.0f){ return false; }
return true;
Also you forged declare u, in this case it not so matter, but in most cases it can be really matter :D

But lets talk about more important things, is a root checking, is a sovlecubic...

I think we have bad results because of something wrong with equation coefficients...

We also have to check all coefficients for zero, and then figure out something, because SolveCubic can return 1 root when line is vertical, and this root will be contain (1.#QNANO) but even if line segment not in curve range, function return true, maybe because check x < 0 || x > 1 is not so good to check wrecked floats.

I also update code upper.

[Edited by - Lolmen on December 6, 2007 9:39:46 AM]

##### Share on other sites
Quote:
 Original post by LolmenWell, this : expression ? true : false :D yep, it's my crazy mania to make code more precise, to have more chances to see results, and not in all cases it will be good :)But this is just a cosmetics typos, it even not wreck the code... :)You have it too, example in point equation :// other code if (u < 0.0f || u > 1.0f) { return false; } else { return true; }// exit funtionAnd we can just use : if (u < 0.0f || u > 1.0f){ return false; } return true;Also you forged declare u, in this case it not so matter, but in most cases it can be really matter :D

u is declared. It’s the last parameter to the function.
The easier way to write that expression is to return the expression of the negated condition of the if. I have corrected the part in my code.

Quote:
 But lets talk about more important things, is a root checking, is a sovlecubic...I think we have bad results because of something wrong with equation coefficients...We also have to check all coefficients for zero, and then figure out something, because SolveCubic can return 1 root when line is vertical, and this root will be contain (1.#QNANO) but even if line segment not in curve range, function return true, maybe because check x < 0 || x > 1 is not so good to check wrecked floats.I also update code upper.

I think the coefficients are correct. Are you sure the function is correct. Have you ever tested it?
Note that a cubic equation cannot have only two real solutions because the complex roots of a polynomial always comes in pairs. So the possibilities are:
1 real solution, 2 non-real solution (complex)
3 real solution

##### Share on other sites
It's also possible to get no real solutions, but I think that can only happen if the cubic is actually a quadratic, and that's pretty easy to test for.

##### Share on other sites

This topic is 3660 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.