| 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 | |