| 408 |
408 |
| 409 def triangle_plane_normal(polygon): |
409 def triangle_plane_normal(polygon): |
| 410 assert(len(polygon.vertices) == 3) |
410 assert(len(polygon.vertices) == 3) |
| 411 a, b, c = polygon.vertices[:3] |
411 a, b, c = polygon.vertices[:3] |
| 412 return cross_product(b - a, b - c) |
412 return cross_product(b - a, b - c) |
| |
413 |
| |
414 def line_intersection_xy(line_1, line_2): |
| |
415 ''' |
| |
416 Computes 2D line intersection. Can return a point outside the given |
| |
417 segments. Z is ignored. |
| |
418 ''' |
| |
419 a, b = line_1.vertices |
| |
420 c, d = line_2.vertices |
| |
421 denominator = (a.x - b.x) * (c.y - d.y) - (a.y - b.y) * (c.x - d.x) |
| |
422 x = (c.x - d.x) * (a.x * b.y - a.y * b.x) |
| |
423 x -= (a.x - b.x) * (c.x * d.y - c.y * d.x) |
| |
424 y = (c.y - d.y) * (a.x * b.y - a.y * b.x) |
| |
425 y -= (a.y - b.y) * (c.x * d.y - c.y * d.x) |
| |
426 try: |
| |
427 x /= denominator |
| |
428 y /= denominator |
| |
429 except ZeroDivisionError: |
| |
430 return None |
| |
431 else: |
| |
432 return Vertex(x, y, 0) |
| |
433 |
| |
434 def line_segment_intersection_xy(line_1, line_2): |
| |
435 ''' |
| |
436 Computes 2D line intersection. Only returns a result if it falls |
| |
437 inside the line segments. Z is ignored. |
| |
438 ''' |
| |
439 from math import inf |
| |
440 intersection = line_intersection_xy(line_1, line_2) |
| |
441 if intersection: |
| |
442 a, b = line_1.vertices |
| |
443 c, d = line_2.vertices |
| |
444 try: |
| |
445 t = (intersection.x - a.x) / (b.x - a.x) |
| |
446 except ZeroDivisionError: |
| |
447 t = inf |
| |
448 try: |
| |
449 u = (intersection.y - a.y) / (b.y - a.y) |
| |
450 except ZeroDivisionError: |
| |
451 u = inf |
| |
452 if 0 < t < 1 or 0 < u < 1: |
| |
453 return intersection |
| |
454 else: |
| |
455 return None |
| |
456 else: |
| |
457 return None |