This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/Logtalk/examples/poem/line2.lgt
2001-06-06 19:40:57 +00:00

93 lines
2.4 KiB
Plaintext

/* A line is defined by its end points. */
/* This class shows examples of calling its own and other class */
/* predicates. */
:- object(line(_Point1, _Point2)).
:- info([
authors is 'Paulo Moura',
version is 1.0,
date is 2000/4/22,
comment is 'Parametric object for representing geometric lines.',
parnames is ['Point1', 'Point2'],
source is 'Example adopted from the POEM system by Ben Staveley-Taylor.']).
:- public(length/1).
:- mode(length(-number), one).
:- public(intersects/1).
:- mode(intersects(+nonvar), one).
:- public(signed_distance/2).
:- mode(signed_distance(+nonvar, -number), one).
:- public(distance/2).
:- mode(distance(+nonvar, -number), one).
length(Length) :-
/* sets Len to the length of the owner line */
parameter(1, P1),
parameter(2, P2),
P1::distance(P2, Length).
intersects(Line2) :-
/* succeeds if Line2 intersects the owner line. */
/* this isn't necessarily a good method, but shows how to */
/* call class procedures from within the class definition. */
parameter(1, P1),
parameter(2, P2),
Line1 = line(P1, P2),
Line2 = line(P3, P4),
Line2::signed_distance(P1, D1),
Line2::signed_distance(P2, D2),
opposite_signs(D1, D2),
Line1::signed_distance(P3, D3),
Line1::signed_distance(P4, D4),
opposite_signs(D3, D4).
signed_distance(Point, Dist) :-
/* finds the perpendicular distance from point to line. */
/* the sign of the answer depends on which side of the */
/* line the point is on. */
parameter(1, P1),
parameter(2, P2),
P1 = point(X1, Y1),
P2 = point(X2, Y2),
Point = point(X3, Y3),
A is X2-X1,
B is Y1-Y2,
C is X1*Y2-X2*Y1,
Dist is (A*Y3+B*X3+C)/sqrt(A*A+B*B).
distance(Point, Dist) :-
/* as 'signed_distance', but Dist always >= 0 */
parameter(1, P1),
parameter(2, P2),
line(P1, P2)::signed_distance(Point, Temp),
Dist is abs(Temp).
/* 'opposite_signs' succeeds if its arguments are of opposite signs. */
/* It has a feature in that 'opposite_signs(0,0)' succeeds: this is */
/* because 0 is treated as having optional sign. */
opposite_signs(A, B) :-
o_s_aux(A, B).
opposite_signs(A, B) :-
o_s_aux(B, A).
o_s_aux(A, B) :-
A >= 0,
B =< 0.
:- end_object.