• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#objective-cqtwindows誰得cocoapythonphprubygameguibathyscaphec翻訳omegat計画中(planning stage)frameworktwittertestdomvb.netdirectxbtronarduinopreviewerゲームエンジン

Mercury Geometry and Math Library


Commit MetaInfo

Revisiond803d6f195accd635e33c76a2ad3eb7e027cd016 (tree)
Zeit2022-03-27 05:18:10
AutorAlaskanEmily <emily@alas...>
CommiterAlaskanEmily

Log Message

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

Ändern Zusammenfassung

Diff

--- a/geometry.segment.m
+++ b/geometry.segment.m
@@ -43,7 +43,7 @@
4343
4444 %------------------------------------------------------------------------------%
4545
46-:- type side ---> left ; right ; collinear.
46+:- type side ---> left ; right ; colinear.
4747
4848 %------------------------------------------------------------------------------%
4949
@@ -82,6 +82,7 @@
8282 %==============================================================================%
8383
8484 :- import_module float.
85+:- import_module vector.vector2.
8586
8687 %------------------------------------------------------------------------------%
8788
@@ -101,7 +102,20 @@ as_tuple(S, {S ^ p1, S ^ p2}).
101102
102103 %------------------------------------------------------------------------------%
103104 % 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+ ).
105119
106120 %------------------------------------------------------------------------------%
107121
--- a/geometry2d.m
+++ b/geometry2d.m
@@ -224,6 +224,8 @@
224224 :- use_module math.
225225 :- import_module float.
226226
227+:- use_module geometry.
228+:- use_module geometry.segment.
227229 :- use_module multi_math.
228230 :- import_module vector.vector2.
229231
@@ -674,32 +676,31 @@ point_to_vector(geometry2d.point(X, Y)) = vector.vector2.vector(X, Y).
674676 Y = min(min(Y1, Y2), Y3),
675677 W = max(max(X1, X2), X3) - X,
676678 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),
679688
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),
682692
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
703704 )
704705 ),
705706 (translate(Point, TriangleIn, TriangleOut) :-
--- a/vector.vector2.m
+++ b/vector.vector2.m
@@ -26,6 +26,10 @@
2626
2727 %------------------------------------------------------------------------------%
2828
29+:- func cross(vector2, vector2) = float.
30+
31+%------------------------------------------------------------------------------%
32+
2933 :- func (vector2::in) + (vector2::in) = (vector2::uo) is det.
3034 :- func (vector2::in) - (vector2::in) = (vector2::uo) is det.
3135 :- func (vector2::in) * (vector2::in) = (vector2::uo) is det.
@@ -117,6 +121,10 @@ get_y(V) = V ^ y.
117121
118122 %------------------------------------------------------------------------------%
119123
124+cross(vector(X1, Y1), vector(X2, Y2)) = (X1 * Y2) - (Y1 * X2).
125+
126+%------------------------------------------------------------------------------%
127+
120128 (vector(X1, Y1)) + (vector(X2, Y2)) = (vector(X1+X2, Y1+Y2)).
121129 (vector(X1, Y1)) - (vector(X2, Y2)) = (vector(X1-X2, Y1-Y2)).
122130 (vector(X1, Y1)) * (vector(X2, Y2)) = (vector(X1*X2, Y1*Y2)).