177 lines
4.6 KiB
Plaintext
177 lines
4.6 KiB
Plaintext
|
|
||
|
/* Points are going to be the fundamental quantity. */
|
||
|
/* These will be defined in Cartesian co-ordinates. */
|
||
|
|
||
|
:- object(point(_X, _Y)).
|
||
|
|
||
|
:- info([
|
||
|
author is 'Paulo Moura',
|
||
|
version is 1.0,
|
||
|
date is 2000/4/22,
|
||
|
comment is 'Parametric object for representing geometric points.',
|
||
|
parnames is ['X', 'Y'],
|
||
|
source is 'Example adopted from the POEM system by Ben Staveley-Taylor.']).
|
||
|
|
||
|
:- public(identical/1).
|
||
|
:- mode(identical(+nonvar), one).
|
||
|
|
||
|
:- public(distance/2).
|
||
|
:- mode(distance(+nonvar, -number), one).
|
||
|
|
||
|
identical(point(X1, Y1)) :-
|
||
|
/* succeeds if the argument and owner points are the same. */
|
||
|
parameter(1, X),
|
||
|
parameter(2, Y),
|
||
|
X1 = X,
|
||
|
Y1 = Y.
|
||
|
|
||
|
distance(point(X1, Y1), Distance) :-
|
||
|
/* finds the distance between argument and owner points. */
|
||
|
parameter(1, X),
|
||
|
parameter(2, Y),
|
||
|
Distance is sqrt((X1-X)*(X1-X)+(Y1-Y)*(Y1-Y)).
|
||
|
|
||
|
:- end_object.
|
||
|
|
||
|
|
||
|
|
||
|
/* 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([
|
||
|
author 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.
|
||
|
|
||
|
|
||
|
|
||
|
/* Ellipses are defined by centre and semi-axes */
|
||
|
|
||
|
:- object(ellipse(_Center, _A, _B)).
|
||
|
|
||
|
:- info([
|
||
|
author is 'Paulo Moura',
|
||
|
version is 1.0,
|
||
|
date is 2000/4/22,
|
||
|
comment is 'Parametric object for representing geometric ellipses.',
|
||
|
parnames is ['Center', 'Rx', 'Ry'],
|
||
|
source is 'Example adopted from the POEM system by Ben Staveley-Taylor.']).
|
||
|
|
||
|
:- public(area/1).
|
||
|
:- mode(area(-number), one).
|
||
|
|
||
|
area(Area) :-
|
||
|
pi(Pi),
|
||
|
parameter(2, A),
|
||
|
parameter(3, B),
|
||
|
Area is Pi*A*B.
|
||
|
|
||
|
pi(3.14196).
|
||
|
|
||
|
:- end_object.
|
||
|
|
||
|
|
||
|
|
||
|
/* Circle is a special form of ellipse */
|
||
|
/* Subclasses ('circle' here) must have the same number of arguments */
|
||
|
/* as their superclass ('ellipse') for the superclass predicates to */
|
||
|
/* be applicable. The arguments may be renamed for clarity. */
|
||
|
|
||
|
:- object(circle(Center, Radius),
|
||
|
extends(ellipse(Center, Radius, Radius))).
|
||
|
|
||
|
:- info([
|
||
|
author is 'Paulo Moura',
|
||
|
version is 1.0,
|
||
|
date is 2000/4/22,
|
||
|
comment is 'Parametric object for representing geometric circles.',
|
||
|
parnames is ['Center', 'Radius'],
|
||
|
source is 'Example adopted from the POEM system by Ben Staveley-Taylor.']).
|
||
|
|
||
|
:- public(circumference/1).
|
||
|
:- mode(circumference(-number), one).
|
||
|
|
||
|
circumference(Circumference) :-
|
||
|
pi(Pi),
|
||
|
parameter(2, Radius),
|
||
|
Circumference is 2*Pi*Radius.
|
||
|
|
||
|
pi(3.14196).
|
||
|
|
||
|
:- end_object.
|