3 Purpose Mainly used for calculating crossings
8 #pragma implementation "liner.cpp"
11 // For compilers that support precompilation, includes "wx/wx.h".
12 #include "wx/wxprec.h"
22 #include "wx/canvas/liner.h"
24 wxLine::wxLine( double x1
, double y1
, double x2
, double y2
)
30 m_a
=wxPoint2DDouble(x1
,y1
);
31 m_b
=wxPoint2DDouble(x2
,y2
);
35 m_valid_parameters
= FALSE
;
42 wxLine::wxLine(const wxPoint2DDouble
& a
,const wxPoint2DDouble
& b
)
49 m_valid_parameters
= FALSE
;
55 // This function decide which action must be taken, after PointInLine
56 // has given the results of two points in relation to a wxLine. See table 1 in the report
58 // input Result_beginPoint:
60 // The results can be R_R_LEFT_SIDE, R_R_RIGHT_SIDE, R_R_ON_AREA, R_R_IN_AREA
62 // return -1: Illegal combination
63 // 0: No action, no crosspoints
64 // 1: Investigate results points in relation to the other wxLine
65 // 2: endPoint is a crosspoint, no further investigation
66 // 3: beginPoint is a crosspoint, no further investigation
67 // 4: beginPoint and endPoint are crosspoints, no further investigation
68 // 5: beginPoint is a crosspoint, need further investigation
69 // 6: endPoint is a crosspoint, need further investigation
70 int wxLine::ActionOnTable1(R_PointStatus Result_beginPoint
, R_PointStatus Result_endPoint
)
72 // beginPoint and endPoint are crosspoints
74 (Result_beginPoint
== R_IN_AREA
)
76 (Result_endPoint
== R_IN_AREA
)
79 // there are no crosspoints, no action
82 (Result_beginPoint
== R_LEFT_SIDE
)
84 (Result_endPoint
== R_LEFT_SIDE
)
88 (Result_beginPoint
== R_RIGHT_SIDE
)
90 (Result_endPoint
== R_RIGHT_SIDE
)
94 // maybe there is a crosspoint, further investigation needed
97 (Result_beginPoint
== R_LEFT_SIDE
)
100 (Result_endPoint
== R_RIGHT_SIDE
)
102 (Result_endPoint
== R_ON_AREA
)
107 (Result_beginPoint
== R_RIGHT_SIDE
)
110 (Result_endPoint
== R_LEFT_SIDE
)
112 (Result_endPoint
== R_ON_AREA
)
117 (Result_beginPoint
== R_ON_AREA
)
120 (Result_endPoint
== R_LEFT_SIDE
)
122 (Result_endPoint
== R_RIGHT_SIDE
)
124 (Result_endPoint
== R_ON_AREA
)
129 //there is a crosspoint
132 (Result_beginPoint
== R_LEFT_SIDE
)
134 (Result_beginPoint
== R_RIGHT_SIDE
)
137 (Result_endPoint
== R_IN_AREA
)
140 // there is a crosspoint
142 (Result_beginPoint
== R_IN_AREA
)
145 (Result_endPoint
== R_LEFT_SIDE
)
147 (Result_endPoint
== R_RIGHT_SIDE
)
151 // beginPoint is a crosspoint, further investigation needed
153 (Result_beginPoint
== R_IN_AREA
)
155 (Result_endPoint
== R_ON_AREA
)
158 // endPoint is a crosspoint, further investigation needed
160 (Result_beginPoint
== R_ON_AREA
)
162 (Result_endPoint
== R_IN_AREA
)
165 // All other combinations are illegal
171 // This function decide which action must be taken, after PointInLine
172 // has given the results of two points in relation to a wxLine. It can only give a
173 // correct decision if first the relation of the points from the wxLine
174 // are investigated in relation to the wxLine wich can be constucted from the points.
176 // input Result_beginPoint:
178 // The results can be R_LEFT_SIDE, R_RIGHT_SIDE, R_ON_AREA, R_IN_AREA
180 // return -1: Illegal combination
181 // 0: No action, no crosspoints
182 // 1: Calculate crosspoint
183 // 2: endPoint is a crosspoint
184 // 3: beginPoint is a crosspoint
185 // 4: beginPoint and endPoint are crosspoints
186 int wxLine::ActionOnTable2(R_PointStatus Result_beginPoint
, R_PointStatus Result_endPoint
)
188 // beginPoint and eindpoint are crosspoints
190 (Result_beginPoint
== R_IN_AREA
)
192 (Result_endPoint
== R_IN_AREA
)
195 // there are no crosspoints
198 (Result_beginPoint
== R_LEFT_SIDE
)
201 (Result_endPoint
== R_LEFT_SIDE
)
203 (Result_endPoint
== R_ON_AREA
)
208 (Result_beginPoint
== R_RIGHT_SIDE
)
211 (Result_endPoint
== R_RIGHT_SIDE
)
213 (Result_endPoint
== R_ON_AREA
)
218 (Result_beginPoint
== R_ON_AREA
)
221 (Result_endPoint
== R_LEFT_SIDE
)
223 (Result_endPoint
== R_RIGHT_SIDE
)
225 (Result_endPoint
== R_ON_AREA
)
230 // there is a real intersection, which must be calculated
233 (Result_beginPoint
== R_LEFT_SIDE
)
235 (Result_endPoint
== R_RIGHT_SIDE
)
239 (Result_beginPoint
== R_RIGHT_SIDE
)
241 (Result_endPoint
== R_LEFT_SIDE
)
245 // endPoint is a crosspoint
248 (Result_beginPoint
== R_LEFT_SIDE
)
250 (Result_beginPoint
== R_RIGHT_SIDE
)
252 (Result_beginPoint
== R_ON_AREA
)
255 (Result_endPoint
== R_IN_AREA
)
258 // beginPoint is a crosspoint
260 (Result_beginPoint
== R_IN_AREA
)
263 (Result_endPoint
== R_LEFT_SIDE
)
265 (Result_endPoint
== R_RIGHT_SIDE
)
267 (Result_endPoint
== R_ON_AREA
)
271 // All other combinations are illegal
275 // Calculate the Y when the X is given
276 double wxLine::Calculate_Y(double X
)
278 CalculateLineParameters();
280 return -(m_AA
* X
+ m_CC
) / m_BB
;
286 void wxLine::Virtual_Point(wxPoint2DDouble
& a_point
,double distance
) const
288 assert(m_valid_parameters
);
290 //calculate the distance using the slope of the wxLine
291 //and rotate 90 degrees
293 a_point
.m_y
=a_point
.m_y
+ (distance
* -m_BB
);
294 a_point
.m_x
=a_point
.m_x
- (distance
* m_AA
);
300 // Calculate the lineparameters for the wxLine if nessecary
302 void wxLine::CalculateLineParameters()
304 // if not valid_parameters calculate the parameters
305 if (!m_valid_parameters
)
309 // bp AND ep may not be the same
313 m_AA
= (m_b
.m_y
- m_a
.m_y
); // A = (Y2-Y1)
314 m_BB
= (m_a
.m_x
- m_b
.m_x
); // B = (X1-X2)
316 // the parameters A end B can now be normalized
317 length
= sqrt(m_AA
*m_AA
+ m_BB
*m_BB
);
321 m_AA
= (m_AA
/ length
);
322 m_BB
= (m_BB
/ length
);
324 m_CC
= -((m_AA
* m_a
.m_x
) + (m_a
.m_y
* m_BB
));
326 m_valid_parameters
= TRUE
;
331 // Checks if a wxLine intersect with another wxLine
332 // inout wxLine : another wxLine
333 // Marge: optional, standard on MARGE (declared in MISC.CPP)
335 // return true : wxLines are crossing
336 // false: wxLines are not crossing
338 bool wxLine::CheckIntersect (wxLine
& lijn
, double Marge
)
342 // bp AND ep may not be the same
346 int Take_Action1
, Take_Action2
;
347 bool Total_Result
=FALSE
;
348 R_PointStatus Result_beginPoint
,Result_endPoint
;
350 Result_beginPoint
= PointInLine(lijn
.m_a
,distance
,Marge
);
351 Result_endPoint
= PointInLine(lijn
.m_b
,distance
,Marge
);
352 Take_Action1
= ActionOnTable1(Result_beginPoint
,Result_endPoint
);
353 switch (Take_Action1
)
355 case 0: Total_Result
= FALSE
; break;
357 Result_beginPoint
= lijn
.PointInLine(m_a
,distance
,Marge
);
358 Result_endPoint
= lijn
.PointInLine(m_b
,distance
,Marge
);
359 Take_Action2
= ActionOnTable2(Result_beginPoint
,Result_endPoint
);
360 switch (Take_Action2
)
362 case 0: Total_Result
= FALSE
; break;
363 case 1: case 2: case 3: case 4: Total_Result
= TRUE
; break;
365 }; break; // This break belongs to the switch(Take_Action1)
366 case 2: case 3: case 4: case 5: case 6: Total_Result
= TRUE
; break;
368 return Total_Result
; //This is the final decision
373 // Get the beginPoint from the wxLine
374 // usage: Point aPoint = a_line.GetBeginPoint()
376 wxPoint2DDouble
wxLine::GetBeginPoint()
383 // Get the endPoint from the wxLine
384 // usage: Point aPoint = a_line.GetEndPoint()
386 wxPoint2DDouble
wxLine::GetEndPoint()
391 // Intersects two wxLines
392 // input wxLine : another wxLine
393 // Marge: optional, standard on MARGE
395 // return 0: If there are no crossings
396 // 1: If there is one crossing
397 // 2: If there are two crossings
398 int wxLine::Intersect(wxLine
& lijn
, wxPoint2DDouble
& c1
,wxPoint2DDouble
& c2
, double Marge
)
402 // bp AND ep may not be the same
406 R_PointStatus Result_beginPoint
,Result_endPoint
;
407 int Take_Action1
, Take_Action2
, Number_of_Crossings
= 0;
409 Result_beginPoint
= PointInLine(lijn
.m_a
,distance
,Marge
);
410 Result_endPoint
= PointInLine(lijn
.m_b
,distance
,Marge
);
412 Take_Action1
= ActionOnTable1(Result_beginPoint
,Result_endPoint
);
413 // 0: No action, no crosspoints
414 // 1: Investigate results points in relation to the other wxLine
415 // 2: endPoint is a crosspoint, no further investigation
416 // 3: beginPoint is a crosspoint, no further investigation
417 // 4: beginPoint and endPoint are crosspoints, no further investigation
418 // 5: beginPoint is a crosspoint, need further investigation
419 // 6: endPoint is a crosspoint, need further investigation
421 // The first switch will insert a crosspoint immediatly
422 switch (Take_Action1
)
424 case 2: case 6: c1
=lijn
.m_b
;
425 Number_of_Crossings
= 1;
427 case 3: case 5: c1
=lijn
.m_a
;
428 Number_of_Crossings
= 1;
432 Number_of_Crossings
= 2;
438 // This switch wil investigate the points of this wxLine in relation to lijn
439 // 1: Investigate results points in relation to the other wxLine
440 // 5: beginPoint is a crosspoint, need further investigation
441 // 6: endPoint is a crosspoint, need further investigation
442 switch (Take_Action1
)
444 case 1: case 5: case 6:
446 Result_beginPoint
= lijn
.PointInLine(m_a
,distance
,Marge
);
447 Result_endPoint
= lijn
.PointInLine(m_b
,distance
,Marge
);
448 Take_Action2
= ActionOnTable2(Result_beginPoint
,Result_endPoint
);
449 // return -1: Illegal combination
450 // 0: No action, no crosspoints
451 // 1: Calculate crosspoint
452 // 2: endPoint is a crosspoint
453 // 3: beginPoint is a crosspoint
454 // 4: beginPoint and endPoint are crosspoints
455 switch (Take_Action2
)
457 // for the cases see the returnvalue of ActionTable2
458 case 1: { // begin of scope to calculate the intersection
459 double X
, Y
, Denominator
;
460 CalculateLineParameters();
461 Denominator
= (m_AA
* lijn
.m_BB
) - (lijn
.m_AA
* m_BB
);
462 // Denominator may not be 0
463 assert(Denominator
!= 0.0);
464 // Calculate intersection of both linesegments
465 X
= ((m_BB
* lijn
.m_CC
) - (lijn
.m_BB
* m_CC
)) / Denominator
;
466 Y
= ((lijn
.m_AA
* m_CC
) - (m_AA
* lijn
.m_CC
)) / Denominator
;
471 Number_of_Crossings
++;
474 Number_of_Crossings
++;
477 Number_of_Crossings
++;
481 Number_of_Crossings
= 2;
489 return Number_of_Crossings
; //This is de final number of crossings
493 // test if a point lies in the linesegment. If the point isn't on the wxLine
494 // the function returns a value that indicates on which side of the
495 // wxLine the point is (in linedirection from first point to second point
497 // returns R_LEFT_SIDE, when point lies on the left side of the wxLine
498 // R_RIGHT_SIDE, when point lies on the right side of the wxLine
499 // R_ON_AREA, when point lies on the infinite wxLine within a range
500 // R_IN_AREA, when point lies in the area of the linesegment
501 // the returnvalues are declared in (wxLine.H)
502 R_PointStatus
wxLine::PointInLine(const wxPoint2DDouble
& a_Point
, double& Distance
,double Marge
)
506 // Point may not be the same
509 int Result_ofm_BBox
=FALSE
;
510 R_PointStatus Result_of_Online
;
512 //quick test if point is begin or endpoint
513 if (a_Point
== m_a
|| a_Point
== m_b
)
516 // Checking if point is in bounding-box with marge
517 double xmin
=wxMin(m_a
.m_x
,m_b
.m_x
);
518 double xmax
=wxMax(m_a
.m_x
,m_b
.m_x
);
519 double ymin
=wxMin(m_a
.m_y
,m_b
.m_y
);
520 double ymax
=wxMax(m_a
.m_y
,m_b
.m_y
);
522 if ( a_Point
.m_x
>= (xmin
- Marge
) && a_Point
.m_x
<= (xmax
+ Marge
) &&
523 a_Point
.m_y
>= (ymin
- Marge
) && a_Point
.m_y
<= (ymax
+ Marge
) )
524 Result_ofm_BBox
=TRUE
;
526 // Checking if point is on the infinite wxLine
527 Result_of_Online
= PointOnLine(a_Point
, Distance
, Marge
);
529 // point in boundingbox of the wxLine and is on the wxLine then the point is R_IN_AREA
530 if ((Result_ofm_BBox
) && (Result_of_Online
== R_ON_AREA
))
533 return Result_of_Online
;
538 // test if a point lies on the wxLine. If the point isn't on the wxLine
539 // the function returns a value that indicates on which side of the
540 // wxLine the point is (in linedirection from first point to second point
542 // returns R_LEFT_SIDE, when point lies on the left side of the wxLine
543 // R_ON_AREA, when point lies on the infinite wxLine within a range
544 // R_RIGHT_SIDE, when point lies on the right side of the wxLine
545 // R_LEFT_SIDE , R_RIGHT_SIDE , R_ON_AREA
546 R_PointStatus
wxLine::PointOnLine(const wxPoint2DDouble
& a_Point
, double& Distance
, double Marge
)
549 // Point may not be queal
552 //quick test if point is begin or endpoint
553 if (a_Point
== m_a
|| a_Point
== m_b
)
556 CalculateLineParameters();
557 // calculate the distance of a_Point in relation to the wxLine
558 Distance
= (m_AA
* a_Point
.m_x
)+(m_BB
* a_Point
.m_y
) + m_CC
;
560 if (Distance
< -Marge
)
564 if (Distance
> Marge
)
571 // makes a wxLine same as these
572 // usage : wxLine1 = wxLine2;
573 wxLine
& wxLine::operator=(const wxLine
& a_line
)
581 m_valid_parameters
= a_line
.m_valid_parameters
;
585 void wxLine::OffsetContour(const wxLine
& nextline
,double factor
,wxPoint2DDouble
& offsetpoint
) const
587 wxPoint2DDouble
offs_begin(m_a
);
588 wxPoint2DDouble
offs_end(m_b
);
590 wxPoint2DDouble
offs_bgn_next(nextline
.m_a
);
591 wxPoint2DDouble
offs_end_next(nextline
.m_b
);
592 // make a wxPoint2DDouble from this point
594 Virtual_Point(offs_begin
,factor
);
595 Virtual_Point(offs_end
,factor
);
596 wxLine
offs_currentline(offs_begin
,offs_end
);
598 nextline
.Virtual_Point(offs_bgn_next
,factor
);
599 nextline
.Virtual_Point(offs_end_next
,factor
);
600 wxLine
offs_nextline(offs_bgn_next
, offs_end_next
);
602 offs_nextline
.CalculateLineParameters();
603 offs_currentline
.CalculateLineParameters();
604 offs_currentline
.Intersect(offs_nextline
,offsetpoint
);
607 // Return the position of the second wxLine compared to this wxLine
608 // Result = IS_ON | IS_LEFT | IS_RIGHT
609 // Here Left and Right is defined as being left or right from
610 // the this wxLine towards the center (common) node
611 // direction of vetors taken as begin to endpoint with end of this at
612 // begin of wxLine two
613 OUTPRODUCT
wxLine::OutProduct(const wxLine
& two
,double accur
)
617 if (two
.m_a
==two
.m_b
)
622 uitp
=PointOnLine(two
.m_b
, distance
, accur
);
625 /*double uitp= (_x - first._x) * (third._y - _y) -
626 (_y - first._y) * (third._x - _x);
627 if (uitp>0) return IS_LEFT;
628 if (uitp<0) return IS_RIGHT;
631 //depending on direction of this link (going to or coming from centre)
632 if (uitp
==R_LEFT_SIDE
)
634 if (uitp
==R_RIGHT_SIDE
)
639 // Intersects two lines if a crossing return TRUE
641 bool wxLine::Intersect(wxLine
& lijn
,wxPoint2DDouble
& crossing
)
644 assert(m_valid_parameters
);
645 assert(lijn
.m_valid_parameters
);
647 double X
, Y
, Denominator
;
648 Denominator
= (m_AA
* lijn
.m_BB
) - (lijn
.m_AA
* m_BB
);
649 // Denominator may not be 0
650 if (Denominator
== 0.0)
652 // Calculate intersection of both linesegments
653 X
= ((m_BB
* lijn
.m_CC
) - (lijn
.m_BB
* m_CC
)) / Denominator
;
654 Y
= ((lijn
.m_AA
* m_CC
) - (m_AA
* lijn
.m_CC
)) / Denominator
;