# mmath

• R/O
• HTTP
• SSH
• HTTPS

## コミット

#### よく使われているワード(クリックで追加)

Mercury Geometry and Math Library

### ログメッセージ

Fix point_inside for triangles, add 2D cross-product to vector2

### 差分

--- a/geometry.segment.m
+++ b/geometry.segment.m
 @@ -43,7 +43,7 @@ 43 43 44 44 %------------------------------------------------------------------------------% 45 45 46 -:- type side ---> left ; right ; collinear. 46 +:- type side ---> left ; right ; colinear. 47 47 48 48 %------------------------------------------------------------------------------% 49 49
 @@ -82,6 +82,7 @@ 82 82 %==============================================================================% 83 83 84 84 :- import_module float. 85 +:- import_module vector.vector2. 85 86 86 87 %------------------------------------------------------------------------------% 87 88
 @@ -101,7 +102,20 @@ as_tuple(S, {S ^ p1, S ^ p2}). 101 102 102 103 %------------------------------------------------------------------------------% 103 104 % TODO! 104 -side(_, _) = collinear. 105 + 106 +side(segment(A, B), C) = Side :- 107 + Cross = vector.vector2.cross(B - A, C - A), 108 + ( if 109 + Cross > float.epsilon 110 + then 111 + Side = left 112 + else if 113 + Cross < -float.epsilon 114 + then 115 + Side = right 116 + else 117 + Side = colinear 118 + ). 105 119 106 120 %------------------------------------------------------------------------------% 107 121
--- a/geometry2d.m
+++ b/geometry2d.m
 @@ -224,6 +224,8 @@ 224 224 :- use_module math. 225 225 :- import_module float. 226 226 227 +:- use_module geometry. 228 +:- use_module geometry.segment. 227 229 :- use_module multi_math. 228 230 :- import_module vector.vector2. 229 231
 @@ -674,32 +676,31 @@ point_to_vector(geometry2d.point(X, Y)) = vector.vector2.vector(X, Y). 674 676 Y = min(min(Y1, Y2), Y3), 675 677 W = max(max(X1, X2), X3) - X, 676 678 H = max(max(Y1, Y2), Y3) - Y), 677 - (point_inside(Triangle, point(PX, PY)) :- 678 - triangle_segments(Triangle, S1, S2, S3), 679 + (point_inside(triangle(X1, Y1, X2, Y2, X3, Y3), point(PX, PY)) :- 680 + % Find the side of the point for each segment 681 + Pos = vector.vector2.vector(PX, PY), 682 + Vector1 = vector.vector2.vector(X1, Y1), 683 + Vector2 = vector.vector2.vector(X2, Y2), 684 + Vector3 = vector.vector2.vector(X3, Y3), 685 + Segment1 = geometry.segment.segment(Vector1, Vector2), 686 + Segment2 = geometry.segment.segment(Vector2, Vector3), 687 + Segment3 = geometry.segment.segment(Vector3, Vector1), 679 688 680 - bounding_box(Triangle) = Bounds, 681 - segment(Bounds ^ rect_x - 1.0, PY, PX, PY) = TestSegment, 689 + Side1 = geometry.segment.side(Segment1, Pos), 690 + Side2 = geometry.segment.side(Segment2, Pos), 691 + Side3 = geometry.segment.side(Segment3, Pos), 682 692 683 - % I tried my best to use existential term instantiation to express an 684 - % exclusive-or disjunction. It didn't work. 685 - % So I'm sorry. I should have done more. 686 - ( collide_segments(TestSegment, S1, _) <=> not ( 687 - collide_segments(TestSegment, S2, _) 688 - ; 689 - collide_segments(TestSegment, S3, _) 690 - ) 691 - ), 692 - ( collide_segments(TestSegment, S2, _) <=> not ( 693 - collide_segments(TestSegment, S1, _) 694 - ; 695 - collide_segments(TestSegment, S3, _) 696 - ) 697 - ), 698 - ( collide_segments(TestSegment, S3, _) <=> not ( 699 - collide_segments(TestSegment, S1, _) 700 - ; 701 - collide_segments(TestSegment, S2, _) 702 - ) 693 + % Either the point must be colinear, or we must be on the same side of 694 + % all three segments. 695 + ( 696 + Side1 = geometry.segment.colinear 697 + ; 698 + Side2 = geometry.segment.colinear 699 + ; 700 + Side3 = geometry.segment.colinear 701 + ; 702 + Side1 = Side2, 703 + Side2 = Side3 703 704 ) 704 705 ), 705 706 (translate(Point, TriangleIn, TriangleOut) :-
--- a/vector.vector2.m
+++ b/vector.vector2.m
 @@ -26,6 +26,10 @@ 26 26 27 27 %------------------------------------------------------------------------------% 28 28 29 +:- func cross(vector2, vector2) = float. 30 + 31 +%------------------------------------------------------------------------------% 32 + 29 33 :- func (vector2::in) + (vector2::in) = (vector2::uo) is det. 30 34 :- func (vector2::in) - (vector2::in) = (vector2::uo) is det. 31 35 :- func (vector2::in) * (vector2::in) = (vector2::uo) is det.
 @@ -117,6 +121,10 @@ get_y(V) = V ^ y. 117 121 118 122 %------------------------------------------------------------------------------% 119 123 124 +cross(vector(X1, Y1), vector(X2, Y2)) = (X1 * Y2) - (Y1 * X2). 125 + 126 +%------------------------------------------------------------------------------% 127 + 120 128 (vector(X1, Y1)) + (vector(X2, Y2)) = (vector(X1+X2, Y1+Y2)). 121 129 (vector(X1, Y1)) - (vector(X2, Y2)) = (vector(X1-X2, Y1-Y2)). 122 130 (vector(X1, Y1)) * (vector(X2, Y2)) = (vector(X1*X2, Y1*Y2)).