Files
secondo/Algebras/PlaneSweep/innerInter
2026-01-23 17:03:45 +08:00

143 lines
4.9 KiB
Plaintext

bool CHalfSegment::innerInter( const CHalfSegment& chs, Point& resp,
CHalfSegment& rchs, bool& first, bool& second ) const
{
resp.SetDefined(false); rchs.SetDefined(false);
first = false; second = false;
Coord xl,yl,xr,yr , Xl,Yl,Xr,Yr;
double k, a, K, A;
xl=lp.GetX(); yl=lp.GetY();
xr=rp.GetX(); yr=rp.GetY();
if (xl!=xr)
{ //k=(yr-yl) / (xr-xl); a=yl - k*yl;
#ifdef RATIONAL_COORDINATES
k=((yr.IsInteger()? yr.IntValue():yr.Value()) -
(yl.IsInteger()? yl.IntValue():yl.Value())) /
((xr.IsInteger()? xr.IntValue():xr.Value()) -
(xl.IsInteger()? xl.IntValue():xl.Value()));
a=(yl.IsInteger()? yl.IntValue():yl.Value()) -
k*(xl.IsInteger()? xl.IntValue():xl.Value());
#else
k=(yr - yl) / (xr - xl);
a=yl - k*xl;
#endif
}
Xl=chs.GetLP().GetX(); Yl=chs.GetLP().GetY();
Xr=chs.GetRP().GetX(); Yr=chs.GetRP().GetY();
if (Xl!=Xr)
{ //K=(Yr-Yl) / (Xr-Xl); A=Yl - K*Xl;
#ifdef RATIONAL_COORDINATES
K= ((Yr.IsInteger()? Yr.IntValue():Yr.Value()) -
(Yl.IsInteger()? Yl.IntValue():Yl.Value())) /
((Xr.IsInteger()? Xr.IntValue():Xr.Value()) -
(Xl.IsInteger()? Xl.IntValue():Xl.Value()));
A = (Yl.IsInteger()? Yl.IntValue():Yl.Value()) -
K*(Xl.IsInteger()? Xl.IntValue():Xl.Value());
#else
K= (Yr - Yl) / (Xr - Xl);
A = Yl - K*Xl;
#endif
}
if ((xl==xr) && (Xl==Xr)) { //both l and L are vertical lines
if (xl!=Xl) return false;
else {
Coord ylow, yup, Ylow, Yup;
if (yl<yr) { ylow=yl; yup=yr; }
else { ylow=yr; yup=yl; }
if (Yl<Yr) { Ylow=Yl; Yup=Yr; }
else { Ylow=Yr; Yup=Yl; }
if (((ylow>Ylow) && (ylow<Yup))|| ((yup>Ylow) && (yup<Yup)) ||
((Ylow>ylow) && (Ylow<yup))|| ((Yup>ylow) && (Yup<yup))) {
Point p1, p2;
if (ylow>Ylow) p1.Set(xl, ylow);
else p1.Set(xl, Ylow);
if (yup<Yup) p2.Set(xl, yup);
else p2.Set(xl, Yup);
rchs.Set(true, p1, p2);
first = true; second = true;
return true;
}
else return false;
}
}
else if (Xl==Xr) { //only L is vertical
if ( xl==Xl && yl>Yl && yl<Yr ) {resp.Set(xl,yl); second = true; return true;}
if ( xr==Xl && yr>Yl && yr<Yr ) {resp.Set(xr,yr); second = true; return true;}
else {
#ifdef RATIONAL_COORDINATES
double y0=k*(Xl.IsInteger()? Xl.IntValue():Xl.Value())+a;
Coord yy(y0);
#else
double y0=k*Xl+a;
Coord yy=y0;
#endif
//(Xl, y0) is the intersection of l and L
if ((Xl>xl) &&( Xl<xr)) {
if ( (yy>=Yl) && (yy <= Yr) ) {
resp.Set (Xl,yy);
first = true;
if ( (yy>Yl) && (yy<Yr) ) second = true;
return true;
}
else return false;
}
}
}
else if (xl==xr) { //only l is vertical
if ( Xl==xl && Yl>yl && Yl<yr ) {resp.Set(Xl,Yl); first = true; return true;}
if ( Xr==xl && Yr>yl && Yr<yr ) {resp.Set(Xr,Yr); first = true; return true;}
else {
#ifdef RATIONAL_COORDINATES
double y0=K*(xl.IsInteger()? xl.IntValue():xl.Value())+A;
Coord yy(y0);
#else
double y0=K*xl+A;
Coord yy=y0;
#endif
//(Xl, y0) is the intersection of l and L
if ((xl>Xl) && (xl<Xr)) {
if ( (yy>=yl) && (yy <= yr) ) {
resp.Set (xl,yy);
second = true;
if ( (yy>yl) && (yy<yr) ) first = true;
return true;
}
else return false;
}
}
}
//otherwise: both *this and *arg are non-vertical lines
if (k==K) { // both lines are parallel or the same
if (a != A) return false; // parallel lines
if (((xl>Xl) && (xl<Xr)) || ((xr>Xl) && (xr<Xr)) ||
((Xl>xl) && (Xl<xr)) || ((Xr>xl) && (Xr<xr))) {
Point p1, p2;
if (xl>Xl) p1.Set(xl, yl);
else p1.Set(Xl, Yl);
if (xr<Xr) p2.Set(xr, yr);
else p2.Set(Xr, Yr);
rchs.Set(true, p1, p2);
first = true; second = true;
return true;
}
else return false;
}
else {
double x0 = (A-a) / (k-K); // y0=x0*k+a;
double y0 = x0*k+a;
#ifdef RATIONAL_COORDINATES
Coord xx(x0); Coord yy(y0);
#else
Coord xx = x0; Coord yy=y0;
#endif
if (GetLP() == chs.GetLP() || GetRP() == chs.GetRP() ) return false;
if ((xx == xl || xx == xr) && xx > Xl && xx < Xr )
{resp.Set(xx,yy); second = true; return true; }
if ( (xx == Xl || xx == Xr) && xx > xl && xx < xr )
{resp.Set(xx,yy); first = true; return true; }
if ((xx>xl) && (xx<xr) && (xx>Xl) && (xx <Xr)) {
resp.Set(xx,yy); first = true; second= true; return true; }
else return false;
}
}