Geometry (Geo) Functions#
A geometry function module.
Point Functions:
ptOffset
ptNeg
ptProduct
ptProductScalar
ptProductVector
ptDistance
ptInBoxp
ptNearestBoxSide
ptSnapToGrid
bBox Functions:
bBoxOffset
bBoxSnapToGrid
bBoxFromSize
bBoxSize
Other Functions:
figFlattenOverlaps
mosFlatten
Geo.ils sourcecode
1 /*****************************************************************
2 * *
3 * Layout Geometry Module *
4 * *
5 * Handles layout geometries such as shapes, points, and *
6 * bounding boxes *
7 * *
8 * * Points are handled by functions starting with pt *
9 * * Bounding boxes are handled by functions starting with *
10 * bBox *
11 * * Figures are handled by functions starting with fig *
12 * * Mosaics are handled by functions starting with mos *
13 * *
14 *****************************************************************/
15
16let((Geo
17 (module_description "Geometry functions")
18 )
19
20Geo = let(()
21
22 ;;;;;;;;;;
23 ; Points ;
24 ;;;;;;;;;;
25 ; Built-in Functions:
26 ; * isLocation
27 ; * xCoord
28 ; * yCoord
29 ; * dbTransformPoint
30 ; * dbTransformPointList
31 ; * dbConcatTransform
32
33 procedure(ptOffset(P offset "ll")
34 "Offset a point or sum 2 points"
35 list(xCoord(P)+xCoord(offset)
36 yCoord(P)+yCoord(offset))
37 )
38
39 procedure(ptNeg(P "l")
40 "Negates both the x and Y of the given point"
41 list(-xCoord(P) -yCoord(P))
42 )
43
44 procedure(ptProduct(P Multiplier "lg")
45 "Multiplies the point, P, by the given Multiplier
46
47 @param P The point as a (X,Y) list
48 @param Multiplier Either a scalar to multiply with both the X and Y or
49 an (X,Y) list containing seperate multipliers for each coordinate"
50 cond(
51 (floatp(Multiplier) || integerp(Multiplier)
52 ptProductScalar(P Multiplier))
53 (isLocation(Multiplier)
54 ptProductVector(P Multiplier))
55 ('t
56 error("Multiplier type is not supported")))
57 )
58
59 procedure(ptProductScalar(P Multiplier "ln")
60 "Multiplys the point, P, by the given scalar Multiplier
61
62 @param P The point as a (X,Y) list
63 @param Multiplier A scalar to multiply with both the X and Y"
64 list(xCoord(P)*Multiplier yCoord(P)*Multiplier)
65 )
66
67 procedure(ptProductVector(P Multiplier "ll")
68 "Multiplys the point, P, by the given scalar Multiplier
69
70 @param P The point as a (X,Y) list
71 @param Multiplier An (X,Y) list containing seperate multipliers for each
72 coordinate"
73 list(xCoord(P)*xCoord(Multiplier) yCoord(P)*yCoord(Multiplier))
74 )
75
76 procedure(ptDistance(P1 P2 "ll")
77 "Calculates the distance between 2 points."
78 sqrt(expt(xCoord(P2) - xCoord(P1) 2) + expt(yCoord(P2) - yCoord(P1) 2)))
79
80 procedure( ptInBoxp( point box "ll")
81 "Checks if the point is inside the bounding box or on the box edge.
82
83 @return inside_box a boolean"
84 xCoord(point) >= leftEdge(box)&&
85 xCoord(point) <= rightEdge(box) &&
86 yCoord(point) >= bottomEdge(box) &&
87 yCoord(point) <= topEdge(box)
88 )
89
90 procedure( ptNearestBoxSide(point box "ll")
91 "Finds the nearest side of the box to the reference point
92 @return side A string, 'left', 'right', 'top', or 'bottom'"
93 let( (x1 y1 x2 y2 x y d1 d2 d3 d4 minDist side)
94
95 x1 = caar( box )
96 y1 = cadar( box )
97 x2 = caadr( box )
98 y2 = cadadr( box )
99
100 x = xCoord( point )
101 y = yCoord( point )
102
103 if(ptInBoxp(point box) then
104 d1 = x - x1 ; left distance
105 d2 = y - y1 ; bottom distance
106 d3 = x2 - x ; right distance
107 d4 = y2 - y ; top distance
108
109 minDist = min( d1 d2 d3 d4 )
110 cond(
111 ( minDist == d1 side = "left")
112 ( minDist == d2 side = "bottom")
113 ( minDist == d3 side = "right")
114 ( minDist == d4 side = "top")
115 )
116 else
117 ; point is outside the box.
118 ; A diagnol line between each corner and the center splits the sides
119 cond(
120 ( x > max(x1 x2) ; To the right of the box
121 side = "right"
122 cond(
123 ( y > max(y1 y2) &&
124 (y - max(y1 y2)) > (x - max(x1 x2))
125 side = "top"
126 )
127 ( y < min(y1 y2) &&
128 (min(y1 y2) - y) > (x - max(x1 x2))
129 side = "bottom"
130 )
131 )
132 )
133 ( x < min(x1 x2) ; To the left of the box
134 side = "left"
135 cond(
136 ( y > max(y1 y2) &&
137 (y - max(y1 y2)) > (min(x1 x2) - x)
138 side = "top"
139 )
140 ( y < min(y1 y2) &&
141 (min(y1 y2) - y) > (min(x1 x2) - x)
142 side = "bottom"
143 )
144 )
145 )
146 ( t ; straight above or below the box
147 cond(
148 ( y > max(y1 y2) side = "top" )
149 ( y < min(y1 y2) side = "bottom" )
150 )
151 )
152 )
153 )
154 side
155 ))
156
157 procedure(ptSnapToGrid( pt grid @optional noLarger)
158 "Snap the point to the grid"
159 numSnapToGrid(xCoord(pt) grid noLarger):
160 numSnapToGrid(yCoord(pt) grid noLarger)
161 )
162
163
164 procedure(numSnapToGrid( number grid @optional noLarger)
165 "Snap a number to the grid"
166 let((out)
167 if( noLarger then
168 out = fix(abs(number)/grid) * grid
169 else
170 out = round(abs(number)/grid) * grid
171 )
172 when(negativep(number) ; negative number
173 out = -out
174 )
175 ))
176
177
178 ;;;;;;;;;;;;;;;;;;
179 ; Bounding Boxes ;
180 ;;;;;;;;;;;;;;;;;;
181 ; Built-in Functions:
182 ; * isBBox
183 ; * dbTransformBBox
184 ; * lowerLeft
185 ; * upperRight
186 ; * centerBox
187 ; * leftEdge
188 ; * rightEdge
189 ; * bottomEdge
190 ; * topEdge
191
192 procedure(bBoxOffset(box offset)
193 "Offset the given bounding box"
194 list(ptOffset(lowerLeft(box) offset)
195 ptOffset(upperRight(box) offset))
196 )
197
198 procedure(bBoxSnapToGrid(box grid)
199 "Snap the bBox to the grid"
200 list(ptSnapToGrid(lowerLeft(box) grid)
201 ptSnapToGrid(upperRight(box) grid))
202 )
203
204 procedure(bBoxFromSize(size "l")
205 "Returns the bounding box with the origin at the center from the size
206 of the bounding box.
207 @param size: A (x,y) list of the size of the bounding box."
208 list(list(-xCoord(size)/2 -yCoord(size)/2)
209 list( xCoord(size)/2 yCoord(size)/2))
210 )
211
212 procedure(bBoxSize(box "l")
213 "Calculate the Size of the bounding box
214 @param box A bounding box list
215 @return size Size of the bounding box as a (x,y) list"
216 list(rightEdge(box)-leftEdge(box)
217 topEdge(box)-bottomEdge(box))
218 )
219
220 ;;;;;;;;;;;;;;;;;;;
221 ; Figure Overlaps ;
222 ;;;;;;;;;;;;;;;;;;;
223 ; Built-in Functions:
224 ; * dbProduceOverlap
225 ; * dbGetOverlaps
226 ; * dbGetTrueOverlaps
227
228 procedure(figFlattenOverlaps(obj "R")
229 "Flattens a hierarchial list of dbObjects returned by the figure overlap
230 functions i.e. dbGetOverlaps, etc
231 @param obj A hierarchial list of obects returned by dbGetOverlaps"
232 let((out)
233 if( atom(obj) && dbobjectp(obj) then
234 ncons(obj)
235 else
236 ;mapcan( 'figFlattenOverlaps obj )
237 out = list()
238 foreach(singleObj obj
239 out=append(out figFlattenOverlaps(singleObj))
240 )
241 out
242 )
243 ))
244
245 ;;;;;;;;;;;
246 ; Mosaics ;
247 ;;;;;;;;;;;
248
249 procedure(mosFlatten(cv)
250 "Flattens all the mosaics up to 5 levels deep in the cell's hierarchy
251 @param cv Cellview object
252 @return 't"
253 foreach( inst cv~>mosaics
254 leFlattenInst(inst 5)
255 )
256 't
257 )
258
259 list(nil
260 'ptOffset ptOffset
261 'ptNeg ptNeg
262 'ptProduct ptProduct
263 'ptDistance ptDistance
264 'ptInBoxp ptInBoxp
265 'ptNearestBoxSide ptNearestBoxSide
266 'ptSnapToGrid ptSnapToGrid
267 'bBoxOffset bBoxOffset
268 'bBoxSnapToGrid bBoxSnapToGrid
269 'bBoxFromSize bBoxFromSize
270 'bBoxSize bBoxSize
271 'figFlattenOverlaps figFlattenOverlaps
272 'mosFlatten mosFlatten
273 )
274)
275
276Import['Module]->New('Geo
277 ?module Geo
278 ?package Import['Virtue]
279 ?description module_description)
280)