Find if a point is within a triangle: Difference between revisions
Content added Content deleted
m (→{{header|Phix}}: also demo\rosetta\Within_triangle.exw) |
|||
Line 120: | Line 120: | ||
Triangle[(0.1, 0.111111111), (12.5, 33.333333333), (-12.5, 16.666666667)] |
Triangle[(0.1, 0.111111111), (12.5, 33.333333333), (-12.5, 16.666666667)] |
||
Point (5.414285714, 14.349206349) is within triangle ? true |
Point (5.414285714, 14.349206349) is within triangle ? true |
||
</pre> |
|||
=={{header|Ada}}== |
|||
This uses a determinant method to calculate the area of triangles, and tests whether or not a point is in a triangle by adding up the areas of the triangles formed by each side of the triangle with the point in question, and seeing if the sum matches the whole. |
|||
It uses a generic two-dimensional geometry, that could be affine, euclidean, or a lot stranger than that. You only need to specify the type of one dimension, and the library ''should'' handle the rest. Edge cases probably exist where they shouldn't, as the area formula might add some imprecision. |
|||
<lang Ada>-- triangle.ads |
|||
generic |
|||
type Dimension is private; |
|||
Zero, Two: Dimension; |
|||
with function "*"(Left, Right: in Dimension) return Dimension is <>; |
|||
with function "/"(Left, Right: in Dimension) return Dimension is <>; |
|||
with function "+"(Left, Right: in Dimension) return Dimension is <>; |
|||
with function "-"(Left, Right: in Dimension) return Dimension is <>; |
|||
with function ">"(Left, Right: in Dimension) return Boolean is <>; |
|||
with function "="(Left, Right: in Dimension) return Boolean is <>; |
|||
with function Image(D: in Dimension) return String is <>; |
|||
package Triangle is |
|||
type Point is record |
|||
X: Dimension; |
|||
Y: Dimension; |
|||
end record; |
|||
type Triangle_T is record |
|||
A,B,C: Point; |
|||
end record; |
|||
function Area(T: in Triangle_T) return Dimension; |
|||
function IsPointInTriangle(P: Point; T: Triangle_T) return Boolean; |
|||
function Image(P: Point) return String is |
|||
("(X="&Image(P.X)&", Y="&Image(P.Y)&")") |
|||
with Inline; |
|||
function Image(T: Triangle_T) return String is |
|||
("(A="&Image(T.A)&", B="&Image(T.B)&", C="&Image(T.C)&")") |
|||
with Inline; |
|||
end; |
|||
</lang> |
|||
<lang Ada>-- triangle.adb |
|||
package body Triangle is |
|||
function Area(T: in Triangle_T) return Dimension |
|||
is |
|||
tmp: Dimension; |
|||
begin |
|||
tmp:=((T.B.X*T.C.Y-T.C.X*T.B.Y)-(T.A.X*T.C.Y-T.C.X*T.A.Y)+(T.A.X*T.B.Y-T.B.X*T.A.Y))/Two; |
|||
if tmp>Zero then |
|||
return tmp; |
|||
else |
|||
return Zero-tmp; |
|||
end if; |
|||
end Area; |
|||
function IsPointInTriangle(P: Point; T: Triangle_T) return Boolean |
|||
is |
|||
begin |
|||
return Area(T)=Area((T.A,T.B,P))+Area((T.A,P,T.C))+Area((P,T.B,T.C)); |
|||
end IsPointInTriangle; |
|||
end; |
|||
</lang> |
|||
<lang Ada>-- test_triangle.adb |
|||
with Ada.Text_IO; |
|||
use Ada.Text_IO; |
|||
with Triangle; |
|||
procedure test_triangle |
|||
is |
|||
package affine_tri is new Triangle(Dimension=>Integer, Zero=>0,Two=>2, Image=>Integer'Image); |
|||
use affine_tri; |
|||
tri1: Triangle_T:=((1,0),(2,0),(0,2)); |
|||
tri2: Triangle_T:=((-1,0),(-1,-1),(2,2)); |
|||
origin: Point:=(0,0); |
|||
begin |
|||
Put_Line("IsPointInTriangle("&Image(origin)&", "&Image(tri1)&") yields "&IsPointInTriangle(origin,tri1)'Image); |
|||
Put_Line("IsPointInTriangle("&Image(origin)&", "&Image(tri2)&") yields "&IsPointInTriangle(origin,tri2)'Image); |
|||
end test_triangle; |
|||
</lang> |
|||
{{out}} |
|||
<pre> |
|||
IsPointInTriangle((X= 0, Y= 0), (A=(X= 1, Y= 0), B=(X= 2, Y= 0), C=(X= 0, Y= 2))) yields FALSE |
|||
IsPointInTriangle((X= 0, Y= 0), (A=(X=-1, Y= 0), B=(X=-1, Y=-1), C=(X= 2, Y= 2))) yields TRUE |
|||
</pre> |
</pre> |
||