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
;