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