home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / contrib / src / canvas / liner.cpp < prev    next >
C/C++ Source or Header  |  2001-06-17  |  20KB  |  661 lines

  1. /*
  2. Program wxLine.CPP
  3. Purpose Mainly used for calculating crossings
  4. Last Update 05-12-1995
  5. */
  6.  
  7. #ifdef __GNUG__
  8. #pragma implementation "liner.cpp"
  9. #endif
  10.  
  11. // For compilers that support precompilation, includes "wx/wx.h".
  12. #include "wx/wxprec.h"
  13.  
  14. #ifdef __BORLANDC__
  15.     #pragma hdrstop
  16. #endif
  17.  
  18. #include <math.h>
  19.  
  20. #include <stdlib.h>
  21.  
  22. #include "wx/canvas/liner.h"
  23.  
  24. wxLine::wxLine( double x1, double y1, double x2, double y2 )
  25. {
  26.     m_AA = 0.0;
  27.     m_BB = 0.0;
  28.     m_CC = 0.0;
  29.  
  30.     m_a=wxPoint2DDouble(x1,y1);
  31.     m_b=wxPoint2DDouble(x2,y2);
  32.     if (m_a==m_b)
  33.         assert(0);
  34.  
  35.     m_valid_parameters = FALSE;
  36. }
  37.  
  38. wxLine::~wxLine()
  39. {
  40. }
  41.  
  42. wxLine::wxLine(const wxPoint2DDouble& a,const wxPoint2DDouble& b)
  43. {
  44.     if (a==b)
  45.         assert(0);
  46.  
  47.     m_a=a;
  48.     m_b=b;
  49.     m_valid_parameters = FALSE;
  50. }
  51.  
  52.  
  53.  
  54. // ActionOnTable1
  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
  57. //
  58. // input Result_beginPoint:
  59. //          Result_endPoint :
  60. //       The results can be R_R_LEFT_SIDE, R_R_RIGHT_SIDE, R_R_ON_AREA, R_R_IN_AREA
  61. //
  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)
  71. {
  72.     // beginPoint and endPoint are crosspoints
  73.     if (
  74.          (Result_beginPoint == R_IN_AREA)
  75.          &&
  76.          (Result_endPoint == R_IN_AREA)
  77.         )
  78.         return 4;
  79.    // there are no crosspoints, no action
  80.     if (
  81.          (
  82.           (Result_beginPoint == R_LEFT_SIDE)
  83.           &&
  84.           (Result_endPoint == R_LEFT_SIDE)
  85.          )
  86.          ||
  87.          (
  88.           (Result_beginPoint == R_RIGHT_SIDE)
  89.           &&
  90.           (Result_endPoint == R_RIGHT_SIDE)
  91.          )
  92.         )
  93.         return 0;
  94.     // maybe there is a crosspoint, further investigation needed
  95.     if (
  96.          (
  97.           (Result_beginPoint == R_LEFT_SIDE)
  98.           &&
  99.           (
  100.             (Result_endPoint == R_RIGHT_SIDE)
  101.             ||
  102.             (Result_endPoint == R_ON_AREA)
  103.           )
  104.          )
  105.          ||
  106.          (
  107.           (Result_beginPoint == R_RIGHT_SIDE)
  108.           &&
  109.           (
  110.             (Result_endPoint == R_LEFT_SIDE)
  111.             ||
  112.             (Result_endPoint == R_ON_AREA)
  113.           )
  114.          )
  115.          ||
  116.          (
  117.           (Result_beginPoint == R_ON_AREA)
  118.           &&
  119.           (
  120.             (Result_endPoint == R_LEFT_SIDE)
  121.             ||
  122.             (Result_endPoint == R_RIGHT_SIDE)
  123.             ||
  124.             (Result_endPoint == R_ON_AREA)
  125.           )
  126.          )
  127.         )
  128.         return 1;
  129.     //there is a crosspoint
  130.     if (
  131.          (
  132.           (Result_beginPoint == R_LEFT_SIDE)
  133.           ||
  134.           (Result_beginPoint == R_RIGHT_SIDE)
  135.          )
  136.          &&
  137.          (Result_endPoint == R_IN_AREA)
  138.         )
  139.         return 2;
  140.     // there is a crosspoint
  141.     if (
  142.          (Result_beginPoint == R_IN_AREA)
  143.          &&
  144.          (
  145.           (Result_endPoint == R_LEFT_SIDE)
  146.           ||
  147.           (Result_endPoint == R_RIGHT_SIDE)
  148.          )
  149.         )
  150.         return 3;
  151.     // beginPoint is a crosspoint, further investigation needed
  152.     if (
  153.          (Result_beginPoint == R_IN_AREA)
  154.          &&
  155.          (Result_endPoint == R_ON_AREA)
  156.         )
  157.         return 5;
  158.     // endPoint is a crosspoint, further investigation needed
  159.     if (
  160.          (Result_beginPoint == R_ON_AREA)
  161.          &&
  162.          (Result_endPoint == R_IN_AREA)
  163.         )
  164.         return 6;
  165.     // All other combinations are illegal
  166.     return -1;
  167. }
  168.  
  169.  
  170. // ActionOnTable2
  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.
  175. //
  176. // input Result_beginPoint:
  177. //          Result_endPoint :
  178. //       The results can be R_LEFT_SIDE, R_RIGHT_SIDE, R_ON_AREA, R_IN_AREA
  179. //
  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)
  187. {
  188.     // beginPoint and eindpoint are crosspoints
  189.     if (
  190.          (Result_beginPoint == R_IN_AREA)
  191.          &&
  192.          (Result_endPoint == R_IN_AREA)
  193.         )
  194.         return 4;
  195.     // there are no crosspoints
  196.     if (
  197.          (
  198.           (Result_beginPoint == R_LEFT_SIDE)
  199.           &&
  200.           (
  201.             (Result_endPoint == R_LEFT_SIDE)
  202.             ||
  203.             (Result_endPoint == R_ON_AREA)
  204.           )
  205.          )
  206.          ||
  207.          (
  208.           (Result_beginPoint == R_RIGHT_SIDE)
  209.           &&
  210.           (
  211.             (Result_endPoint == R_RIGHT_SIDE)
  212.             ||
  213.             (Result_endPoint == R_ON_AREA)
  214.           )
  215.          )
  216.          ||
  217.          (
  218.           (Result_beginPoint == R_ON_AREA)
  219.           &&
  220.           (
  221.             (Result_endPoint == R_LEFT_SIDE)
  222.             ||
  223.             (Result_endPoint == R_RIGHT_SIDE)
  224.             ||
  225.             (Result_endPoint == R_ON_AREA)
  226.           )
  227.          )
  228.         )
  229.         return 0;
  230.     // there is a real intersection, which must be calculated
  231.     if (
  232.          (
  233.           (Result_beginPoint == R_LEFT_SIDE)
  234.           &&
  235.           (Result_endPoint == R_RIGHT_SIDE)
  236.          )
  237.          ||
  238.          (
  239.           (Result_beginPoint == R_RIGHT_SIDE)
  240.           &&
  241.           (Result_endPoint == R_LEFT_SIDE)
  242.          )
  243.         )
  244.         return 1;
  245.     // endPoint is a crosspoint
  246.     if (
  247.          (
  248.           (Result_beginPoint == R_LEFT_SIDE)
  249.           ||
  250.           (Result_beginPoint == R_RIGHT_SIDE)
  251.           ||
  252.           (Result_beginPoint == R_ON_AREA)
  253.          )
  254.          &&
  255.          (Result_endPoint == R_IN_AREA)
  256.         )
  257.         return 2;
  258.     // beginPoint is a crosspoint
  259.     if (
  260.          (Result_beginPoint == R_IN_AREA)
  261.          &&
  262.          (
  263.           (Result_endPoint == R_LEFT_SIDE)
  264.           ||
  265.           (Result_endPoint == R_RIGHT_SIDE)
  266.           ||
  267.           (Result_endPoint == R_ON_AREA)
  268.          )
  269.         )
  270.         return 3;
  271.     // All other combinations are illegal
  272.     return -1;
  273. }
  274.  
  275. // Calculate the Y when the X is given
  276. double wxLine::Calculate_Y(double X)
  277. {
  278.     CalculateLineParameters();
  279.     if (m_AA != 0)
  280.         return -(m_AA * X + m_CC) / m_BB;
  281.     else
  282.         // horizontal wxLine
  283.         return m_a.m_y;
  284. }
  285.  
  286. void wxLine::Virtual_Point(wxPoint2DDouble& a_point,double distance)  const
  287. {
  288.     assert(m_valid_parameters);
  289.  
  290.     //calculate the distance using the slope of the wxLine
  291.    //and rotate 90 degrees
  292.  
  293.     a_point.m_y=a_point.m_y + (distance * -m_BB);
  294.     a_point.m_x=a_point.m_x - (distance * m_AA );
  295. }
  296.  
  297.  
  298.  
  299. //
  300. // Calculate the lineparameters for the wxLine if nessecary
  301. //
  302. void wxLine::CalculateLineParameters()
  303. {
  304.     // if not valid_parameters calculate the parameters
  305.     if (!m_valid_parameters)
  306.     {
  307.         double length;
  308.  
  309.         // bp AND ep may not be the same
  310.         if (m_a == m_b)
  311.             assert (0);
  312.  
  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)
  315.  
  316.         // the parameters A end B can now be normalized
  317.         length = sqrt(m_AA*m_AA + m_BB*m_BB);
  318.  
  319.         assert(length !=0);
  320.  
  321.         m_AA = (m_AA / length);
  322.         m_BB = (m_BB / length);
  323.  
  324.         m_CC = -((m_AA * m_a.m_x) + (m_a.m_y * m_BB));
  325.  
  326.         m_valid_parameters = TRUE;
  327.     }
  328. }
  329.  
  330.  
  331. // Checks if a wxLine intersect with another wxLine
  332. // inout    wxLine : another wxLine
  333. //          Marge: optional, standard on MARGE (declared in MISC.CPP)
  334. //
  335. // return   true : wxLines are crossing
  336. //          false: wxLines are not crossing
  337. //
  338. bool wxLine::CheckIntersect (wxLine& lijn, double Marge)
  339. {
  340.     double distance=0;
  341.  
  342.    // bp AND ep may not be the same
  343.    if (m_a == m_b)
  344.       assert (0);
  345.  
  346.     int Take_Action1, Take_Action2;
  347.     bool Total_Result=FALSE;
  348.     R_PointStatus Result_beginPoint,Result_endPoint;
  349.  
  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)
  354.     {
  355.         case 0: Total_Result = FALSE ; break;
  356.         case 1: {
  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)
  361.                         {
  362.                             case 0: Total_Result = FALSE; break;
  363.                             case 1: case 2: case 3: case 4: Total_Result = TRUE; break;
  364.                         }
  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;
  367.     }
  368.     return Total_Result; //This is the final decision
  369. }
  370.  
  371.  
  372. //
  373. // Get the beginPoint from the wxLine
  374. // usage: Point aPoint = a_line.GetBeginPoint()
  375. //
  376. wxPoint2DDouble wxLine::GetBeginPoint()
  377. {
  378.   return m_a;
  379. }
  380.  
  381.  
  382. //
  383. // Get the endPoint from the wxLine
  384. // usage: Point aPoint = a_line.GetEndPoint()
  385. //
  386. wxPoint2DDouble wxLine::GetEndPoint()
  387. {
  388.     return m_b;
  389. }
  390.  
  391. // Intersects two wxLines
  392. // input    wxLine : another wxLine
  393. //          Marge: optional, standard on MARGE
  394. //
  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)
  399. {
  400.     double distance=0;
  401.  
  402.     // bp AND ep may not be the same
  403.     if (m_a == m_b)
  404.         assert (0);
  405.  
  406.     R_PointStatus Result_beginPoint,Result_endPoint;
  407.     int Take_Action1, Take_Action2, Number_of_Crossings = 0;
  408.  
  409.     Result_beginPoint = PointInLine(lijn.m_a,distance,Marge);
  410.     Result_endPoint   = PointInLine(lijn.m_b,distance,Marge);
  411.  
  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
  420.  
  421.     // The first switch will insert a crosspoint immediatly
  422.     switch (Take_Action1)
  423.     {
  424.         case 2: case 6: c1=lijn.m_b;
  425.                         Number_of_Crossings = 1;
  426.                         break;
  427.         case 3: case 5: c1=lijn.m_a;
  428.                         Number_of_Crossings = 1;
  429.                         break;
  430.         case 4:         c1=lijn.m_a;
  431.                         c2=lijn.m_b;
  432.                         Number_of_Crossings = 2;
  433.                         break;
  434.         default:
  435.                         break;
  436.     }
  437.  
  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)
  443.     {
  444.         case 1: case 5: case 6:
  445.         {
  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)
  456.             {
  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;
  467.  
  468.                             c1.m_x=X;
  469.                             c1.m_y=Y;
  470.                          }
  471.                          Number_of_Crossings++;
  472.                          break;
  473.                 case 2:  c2=m_a;
  474.                          Number_of_Crossings++;
  475.                          break;
  476.                 case 3:  c2=m_b;
  477.                          Number_of_Crossings++;
  478.                          break;
  479.                 case 4:  c1=m_a;
  480.                          c2=m_b;
  481.                          Number_of_Crossings = 2;
  482.                          break;
  483.             }
  484.         };
  485.         break;
  486.         default:
  487.              break;
  488.     }
  489.     return Number_of_Crossings; //This is de final number of crossings
  490. }
  491.  
  492. //
  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
  496. //
  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)
  503. {
  504.     Distance=0;
  505.  
  506.     // Point may not be the same
  507.     assert(m_a != m_b);
  508.  
  509.     int Result_ofm_BBox=FALSE;
  510.     R_PointStatus Result_of_Online;
  511.  
  512.     //quick test if point is begin or endpoint
  513.     if (a_Point == m_a || a_Point == m_b)
  514.         return R_IN_AREA;
  515.  
  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);
  521.  
  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;
  525.  
  526.     // Checking if point is on the infinite wxLine
  527.     Result_of_Online = PointOnLine(a_Point, Distance, Marge);
  528.  
  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))
  531.         return R_IN_AREA;
  532.     else
  533.         return Result_of_Online;
  534. }
  535.  
  536.  
  537. //
  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
  541. //
  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)
  547. {
  548.     Distance=0;
  549.     // Point may not be queal
  550.     assert(m_a!=m_b);
  551.  
  552.     //quick test if point is begin or endpoint
  553.     if (a_Point == m_a || a_Point == m_b)
  554.         return R_ON_AREA;
  555.  
  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;
  559.  
  560.     if (Distance < -Marge)
  561.         return R_LEFT_SIDE;
  562.     else
  563.     {
  564.         if (Distance > Marge)
  565.             return R_RIGHT_SIDE;
  566.         else
  567.             return R_ON_AREA;
  568.     }
  569. }
  570.  
  571. // makes a wxLine same as these
  572. // usage : wxLine1 = wxLine2;
  573. wxLine& wxLine::operator=(const wxLine& a_line)
  574. {
  575.     m_AA = a_line.m_AA;
  576.     m_BB = a_line.m_BB;
  577.     m_CC = a_line.m_CC;
  578.  
  579.     m_a= a_line.m_a;
  580.     m_b= a_line.m_b;
  581.     m_valid_parameters = a_line.m_valid_parameters;
  582.     return *this;
  583. }
  584.  
  585. void wxLine::OffsetContour(const wxLine& nextline,double factor,wxPoint2DDouble& offsetpoint)  const
  586. {
  587.     wxPoint2DDouble offs_begin(m_a);
  588.     wxPoint2DDouble offs_end(m_b);
  589.  
  590.     wxPoint2DDouble offs_bgn_next(nextline.m_a);
  591.     wxPoint2DDouble offs_end_next(nextline.m_b);
  592.     // make a wxPoint2DDouble from this point
  593.  
  594.     Virtual_Point(offs_begin,factor);
  595.     Virtual_Point(offs_end,factor);
  596.     wxLine  offs_currentline(offs_begin,offs_end);
  597.  
  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);
  601.  
  602.     offs_nextline.CalculateLineParameters();
  603.     offs_currentline.CalculateLineParameters();
  604.     offs_currentline.Intersect(offs_nextline,offsetpoint);
  605. }
  606.  
  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)
  614. {
  615.     R_PointStatus uitp;
  616.     double distance;
  617.     if (two.m_a==two.m_b)
  618.         assert(0);
  619.     if (m_a==m_b)
  620.         assert(0);
  621.  
  622.     uitp=PointOnLine(two.m_b, distance, accur);
  623.  
  624.  
  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;
  629.     return IS_ON;*/
  630.  
  631.     //depending on direction of this link (going to or coming from centre)
  632.     if (uitp==R_LEFT_SIDE)
  633.         return R_IS_LEFT;
  634.     if (uitp==R_RIGHT_SIDE)
  635.         return R_IS_RIGHT;
  636.     return R_IS_ON;
  637. }
  638.  
  639. // Intersects two lines if a crossing return TRUE
  640. // else FALSE
  641. bool wxLine::Intersect(wxLine& lijn,wxPoint2DDouble& crossing)
  642. {
  643.     // lijn must exist
  644.     assert(m_valid_parameters);
  645.     assert(lijn.m_valid_parameters);
  646.  
  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)
  651.         return FALSE;
  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;
  655.  
  656.     crossing.m_x=X;
  657.     crossing.m_y=Y;
  658.     return TRUE;
  659. }
  660.  
  661.