1 /* Part of XPCE --- The SWI-Prolog GUI toolkit
2
3 Author: Jan Wielemaker and Anjo Anjewierden
4 E-mail: jan@swi.psy.uva.nl
5 WWW: http://www.swi.psy.uva.nl/projects/xpce/
6 Copyright (c) 1985-2002, University of Amsterdam
7 All rights reserved.
8
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions
11 are met:
12
13 1. Redistributions of source code must retain the above copyright
14 notice, this list of conditions and the following disclaimer.
15
16 2. Redistributions in binary form must reproduce the above copyright
17 notice, this list of conditions and the following disclaimer in
18 the documentation and/or other materials provided with the
19 distribution.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #include <h/kernel.h>
36 #include <h/graphics.h>
37 #include <math.h>
38
39 static status
initialisePoint(Point p,Int x,Int y)40 initialisePoint(Point p, Int x, Int y)
41 { if ( isDefault(x) ) x = ZERO;
42 if ( isDefault(y) ) y = ZERO;
43 assign(p, x, x);
44 assign(p, y, y);
45
46 succeed;
47 }
48
49
50 static Point
getConvertPoint(Class class,Any obj)51 getConvertPoint(Class class, Any obj)
52 { if ( instanceOfObject(obj, ClassEvent) )
53 return getPositionEvent((EventObj) obj, DEFAULT);
54 else
55 { CharArray ca = obj;
56 int x, y;
57
58 if ( isstrA(&ca->data) &&
59 sscanf((char *)ca->data.s_textA, "%d,%d", &x, &y) == 2 )
60 answer(newObject(ClassPoint, toInt(x), toInt(y), EAV));
61 }
62
63 fail;
64 }
65
66
67 static StringObj
getPrintNamePoint(Point p)68 getPrintNamePoint(Point p)
69 { char buf[200];
70
71 sprintf(buf, INTPTR_FORMAT "," INTPTR_FORMAT, valInt(p->x), valInt(p->y));
72 answer(CtoString(buf));
73 }
74
75
76 status
equalPoint(Point p1,Point p2)77 equalPoint(Point p1, Point p2)
78 { if (p1->x == p2->x && p1->y == p2->y)
79 succeed;
80 fail;
81 }
82
83
84 status
copyPoint(Point p1,Point p2)85 copyPoint(Point p1, Point p2)
86 { assign(p1, x, p2->x);
87 assign(p1, y, p2->y);
88
89 succeed;
90 }
91
92
93 static Point
getCopyPoint(Point p)94 getCopyPoint(Point p)
95 { answer(answerObject(p->class, p->x, p->y, EAV));
96 }
97
98
99 status
setPoint(Point pt,Int x,Int y)100 setPoint(Point pt, Int x, Int y)
101 { if ( notDefault(x) ) assign(pt, x, x);
102 if ( notDefault(y) ) assign(pt, y, y);
103
104 succeed;
105 }
106
107
108 status
offsetPoint(Point pt,Int x,Int y)109 offsetPoint(Point pt, Int x, Int y)
110 { assign(pt, x, add(x,pt->x));
111 assign(pt, y, add(y,pt->y));
112
113 succeed;
114 }
115
116
117 static Point
getDifferencePoint(Point p,Point q)118 getDifferencePoint(Point p, Point q)
119 { answer(answerObject(ClassPoint, sub(p->x,q->x), sub(p->y,q->y),EAV));
120 }
121
122
123 int
get_distance_point(Point p,int x,int y)124 get_distance_point(Point p, int x, int y)
125 { double px = (double)valInt(p->x);
126 double py = (double)valInt(p->y);
127 double qx = (double)x;
128 double qy = (double)y;
129 double d = sqrt((qx-px)*(qx-px) + (qy-py)*(qy-py));
130
131 return (int)d;
132 }
133
134
135 Int
getDistancePoint(Point p,Point q)136 getDistancePoint(Point p, Point q)
137 { double px = (double)valInt(p->x);
138 double py = (double)valInt(p->y);
139 double qx = (double)valInt(q->x);
140 double qy = (double)valInt(q->y);
141 double d = sqrt((qx-px)*(qx-px) + (qy-py)*(qy-py));
142 long di = (long)d;
143
144 answer(toInt(di));
145 }
146
147
148 Point
getMidPoint(Point p,Point q)149 getMidPoint(Point p, Point q)
150 { answer(answerObject(ClassPoint,
151 toInt((valInt(p->x)+valInt(q->x)+1)/2),
152 toInt((valInt(p->y)+valInt(q->y)+1)/2),
153 EAV));
154 }
155
156
157 status
plusPoint(Point p,Point q)158 plusPoint(Point p, Point q)
159 { assign(p, x, add(p->x,q->x));
160 assign(p, y, add(p->y,q->y));
161
162 succeed;
163 }
164
165
166 status
minusPoint(Point p,Point q)167 minusPoint(Point p, Point q)
168 { assign(p, x, sub(p->x,q->x));
169 assign(p, y, sub(p->y,q->y));
170
171 succeed;
172 }
173
174
175 static status
mirrorPoint(Point p,Point q)176 mirrorPoint(Point p, Point q)
177 { Int mx = ZERO, my = ZERO;
178
179 if ( notDefault(q) )
180 { mx = q->x;
181 my = q->y;
182 }
183
184 assign(p, x, sub(mx, p->x));
185 assign(p, y, sub(my, p->y));
186
187 succeed;
188 }
189
190
191 static Point
getPlusPoint(Point p1,Point p2)192 getPlusPoint(Point p1, Point p2)
193 { Point p = getCopyPoint(p1);
194
195 plusPoint(p, p2);
196
197 answer(p);
198 }
199
200
201 static Point
getMinusPoint(Point p1,Point p2)202 getMinusPoint(Point p1, Point p2)
203 { Point p = getCopyPoint(p1);
204
205 minusPoint(p, p2);
206
207 answer(p);
208 }
209
210
211 static Point
getMirrorPoint(Point p1,Point p2)212 getMirrorPoint(Point p1, Point p2)
213 { Point p = getCopyPoint(p1);
214
215 mirrorPoint(p, p2);
216
217 answer(p);
218 }
219
220
221 /* Type declaractions */
222
223 static char *T_offset[] = { "dx=int", "dy=int" };
224 static char *T_xADintD_yADintD[] = { "x=[int]", "y=[int]" };
225
226 /* Instance Variables */
227
228 static vardecl var_point[] =
229 { IV(NAME_x, "int", IV_BOTH,
230 NAME_dimension, "x-coordinate of point"),
231 IV(NAME_y, "int", IV_BOTH,
232 NAME_dimension, "y-coordinate of point")
233 };
234
235 /* Send Methods */
236
237 static senddecl send_point[] =
238 { SM(NAME_initialise, 2, T_xADintD_yADintD, initialisePoint,
239 DEFAULT, "Create point from x- and y-value"),
240 SM(NAME_minus, 1, "point", minusPoint,
241 NAME_calculate, "Subtract x and y of argument point"),
242 SM(NAME_mirror, 1, "origin=[point]", mirrorPoint,
243 NAME_calculate, "Mirror point around argument or (0,0)"),
244 SM(NAME_offset, 2, T_offset, offsetPoint,
245 NAME_calculate, "Move the point by given x and y"),
246 SM(NAME_plus, 1, "point", plusPoint,
247 NAME_calculate, "Add x- and y-values of argument point"),
248 SM(NAME_set, 2, T_xADintD_yADintD, setPoint,
249 NAME_calculate, "Set x- and y-values"),
250 SM(NAME_equal, 1, "to=point", equalPoint,
251 NAME_compare, "Test if argument is same position"),
252 SM(NAME_copy, 1, "from=point", copyPoint,
253 NAME_copy, "Copy x- and y values from the argument")
254 };
255
256 /* Get Methods */
257
258 static getdecl get_point[] =
259 { GM(NAME_difference, 1, "point", "to=point", getDifferencePoint,
260 NAME_calculate, "New point that reflects distance"),
261 GM(NAME_distance, 1, "int", "to=point", getDistancePoint,
262 NAME_calculate, "Integer for distance between points"),
263 GM(NAME_mid, 1, "point", "to=point", getMidPoint,
264 NAME_calculate, "New point in the middle between points"),
265 GM(NAME_minus, 1, "point", "point", getMinusPoint,
266 NAME_calculate, "New point p1 - p2"),
267 GM(NAME_mirror, 1, "point", "origin=[point]", getMirrorPoint,
268 NAME_calculate, "New point mirrored over argument"),
269 GM(NAME_plus, 1, "point", "point", getPlusPoint,
270 NAME_calculate, "New point p1 + p2"),
271 GM(NAME_copy, 0, "point", NULL, getCopyPoint,
272 NAME_copy, "New point with same <-x and <-y"),
273 GM(NAME_convert, 1, "point", "event|char_array", getConvertPoint,
274 NAME_textual, "Event <-position or the text `x,y'"),
275 GM(NAME_printName, 0, "string", NULL, getPrintNamePoint,
276 NAME_textual, "Printed representation as %d,%d")
277 };
278
279 /* Resources */
280
281 #define rc_point NULL
282 /*
283 static classvardecl rc_point[] =
284 {
285 };
286 */
287
288 /* Class Declaration */
289
290 static Name point_termnames[] = { NAME_x, NAME_y };
291
292 ClassDecl(point_decls,
293 var_point, send_point, get_point, rc_point,
294 2, point_termnames,
295 "$Rev$");
296
297 status
makeClassPoint(Class class)298 makeClassPoint(Class class)
299 { return declareClass(class, &point_decls);
300 }
301