1 /***************************************************************************
2 SCED - Schematic Capture Editor
3 JSPICE3 adaptation of Spice3e2 - Copyright (c) Stephen R. Whiteley 1992
4 Copyright 1990 Regents of the University of California. All rights reserved.
5 Authors: 1981 Giles C. Billingsley (parts of KIC layout editor)
6 1992 Stephen R. Whiteley
7 ****************************************************************************/
8
9 /*
10 * Transforms package.
11 */
12
13 #include "cddefs.h"
14 #include <string.h>
15
16 struct tt {
17 long ttMatrix[3][3];
18 struct tt *ttNext;
19 };
20 static struct tt *Transforms;
21
22 void
TInit()23 TInit()
24 {
25 struct tt *Tmp;
26
27 for (Tmp = Transforms; Tmp; Tmp = Transforms) {
28 Transforms = Tmp->ttNext;
29 tfree(Tmp);
30 }
31 Transforms = alloc(tt);
32 if (Transforms == NULL) MallocFailed();
33 Transforms->ttNext = NULL;
34 TIdentity();
35 }
36
37 int
TEmpty()38 TEmpty()
39 {
40 if (Transforms == NULL)
41 return(True);
42 else
43 return(False);
44 }
45
46 int
TFull()47 TFull()
48 {
49 return(False);
50 }
51
52 void
TPush()53 TPush()
54 {
55 struct tt *Tmp;
56
57 Tmp = alloc(tt);
58 if (Tmp == NULL) MallocFailed();
59 Tmp->ttNext = Transforms;
60 Transforms = Tmp;
61 }
62
63 void
TPop()64 TPop()
65 {
66 struct tt *Tmp;
67
68 Tmp = Transforms;
69 Transforms = Tmp->ttNext;
70 tfree(Tmp);
71 }
72
73 void
TCurrent(TFP)74 TCurrent(TFP)
75 long *TFP;
76 {
77 int i,j;
78
79 for(i = 0; i < 3; ++i)
80 for(j = 0; j<3; ++j)
81 TFP[(3 * i) + j] = Transforms->ttMatrix[i][j];
82 }
83
84 void
TLoadCurrent(TFP)85 TLoadCurrent(TFP)
86 long *TFP;
87 {
88 int i,j;
89
90 for(i = 0; i < 3; ++i)
91 for(j = 0; j < 3; ++j)
92 Transforms->ttMatrix[i][j] = TFP[(3 * i) + j];
93 }
94
95 void
TTranslate(X,Y)96 TTranslate(X,Y)
97 long X,Y;
98 {
99 Transforms->ttMatrix[2][0] += X;
100 Transforms->ttMatrix[2][1] += Y;
101 }
102
103 void
TMY()104 TMY()
105 {
106 Transforms->ttMatrix[0][1] = -Transforms->ttMatrix[0][1];
107 Transforms->ttMatrix[1][1] = -Transforms->ttMatrix[1][1];
108 Transforms->ttMatrix[2][1] = -Transforms->ttMatrix[2][1];
109 }
110
111 void
TMX()112 TMX()
113 {
114 Transforms->ttMatrix[0][0] = -Transforms->ttMatrix[0][0];
115 Transforms->ttMatrix[1][0] = -Transforms->ttMatrix[1][0];
116 Transforms->ttMatrix[2][0] = -Transforms->ttMatrix[2][0];
117 }
118
119 void
TRotate(XDirection,YDirection)120 TRotate(XDirection,YDirection)
121 long XDirection,YDirection;
122 {
123 /*
124 Rotation angle is expressed as a CIF-style direction vector.
125 */
126 long Int1;
127
128 if (XDirection == 0){
129 if (Abs(YDirection) > 1)
130 if (YDirection < 0)
131 YDirection = -1;
132 else
133 YDirection = 1;
134 }
135 elif (YDirection == 0){
136 if (Abs(XDirection) > 1)
137 if (XDirection < 0)
138 XDirection = -1;
139 else
140 XDirection = 1;
141 }
142 if (XDirection == 1 And YDirection == 0)
143 /*
144 Don't rotate at all.
145 */
146 return;
147 elif (XDirection == 0 And YDirection == -1){
148 /*
149 Rotate ccw by 270 degrees.
150 */
151 Int1 = Transforms->ttMatrix[0][0];
152 Transforms->ttMatrix[0][0] = Transforms->ttMatrix[0][1];
153 Transforms->ttMatrix[0][1] = -Int1;
154 Int1 = Transforms->ttMatrix[1][0];
155 Transforms->ttMatrix[1][0] = Transforms->ttMatrix[1][1];
156 Transforms->ttMatrix[1][1] = -Int1;
157 Int1 = Transforms->ttMatrix[2][0];
158 Transforms->ttMatrix[2][0] = Transforms->ttMatrix[2][1];
159 Transforms->ttMatrix[2][1] = -Int1;
160 }
161 elif (XDirection == 0 And YDirection == 1){
162 /*
163 Rotate ccw by 90 degrees.
164 */
165 Int1 = Transforms->ttMatrix[0][0];
166 Transforms->ttMatrix[0][0] = -Transforms->ttMatrix[0][1];
167 Transforms->ttMatrix[0][1] = Int1;
168 Int1 = Transforms->ttMatrix[1][0];
169 Transforms->ttMatrix[1][0] = -Transforms->ttMatrix[1][1];
170 Transforms->ttMatrix[1][1] = Int1;
171 Int1 = Transforms->ttMatrix[2][0];
172 Transforms->ttMatrix[2][0] = -Transforms->ttMatrix[2][1];
173 Transforms->ttMatrix[2][1] = Int1;
174 }
175 elif (XDirection == -1 And YDirection == 0){
176 /*
177 Rotate ccw by 180 degrees.
178 */
179 Transforms->ttMatrix[0][0] = -Transforms->ttMatrix[0][0];
180 Transforms->ttMatrix[0][1] = -Transforms->ttMatrix[0][1];
181 Transforms->ttMatrix[1][0] = -Transforms->ttMatrix[1][0];
182 Transforms->ttMatrix[1][1] = -Transforms->ttMatrix[1][1];
183 Transforms->ttMatrix[2][0] = -Transforms->ttMatrix[2][0];
184 Transforms->ttMatrix[2][1] = -Transforms->ttMatrix[2][1];
185 }
186 }
187
188 void
TIdentity()189 TIdentity()
190 {
191 long *l;
192
193 l = (long *)Transforms->ttMatrix;
194 *l++ = 1; *l++ = 0; *l++ = 0;
195 *l++ = 0; *l++ = 1; *l++ = 0;
196 *l++ = 0; *l++ = 0; *l++ = 1;
197 }
198
199 void
TPoint(X,Y)200 TPoint(X,Y)
201 long *X,*Y;
202 {
203 /*
204 Transform the point.
205 */
206 long Int1;
207
208 Int1 = *X*Transforms->ttMatrix[0][0] + *Y*Transforms->ttMatrix[1][0] +
209 Transforms->ttMatrix[2][0];
210 *Y = *X*Transforms->ttMatrix[0][1] + *Y*Transforms->ttMatrix[1][1] +
211 Transforms->ttMatrix[2][1];
212 *X = Int1;
213 }
214
215 void
TPremultiply()216 TPremultiply()
217 {
218 /*
219 * Form the instance transform.
220 * This is done by computing
221 * Transforms->ttMatrix * Transforms->ttNext->ttMatrix and
222 * placing the product in Transforms.ttMatrix.
223 * So, the scenario for transforming the coordinates of a master follows.
224 * TPush();
225 * TIdentity();
226 * Invoke TMX, Translate, etc. to build instance transform.
227 * Form the instance transform.
228 * TPremultiply();
229 * Invoke TPoint to transform master points to instance points.
230 * TPop();
231 */
232
233 long Int1,Int2,Int3,Int4,Int5,Int6;
234 int SP;
235 struct tt *Next;
236
237 Next = Transforms->ttNext;
238
239 Int1 = Transforms->ttMatrix[0][0]*Next->ttMatrix[0][0] +
240 Transforms->ttMatrix[0][1]*Next->ttMatrix[1][0];
241
242 Int2 = Transforms->ttMatrix[0][0]*Next->ttMatrix[0][1] +
243 Transforms->ttMatrix[0][1]*Next->ttMatrix[1][1];
244
245 Int3 = Transforms->ttMatrix[1][0]*Next->ttMatrix[0][0] +
246 Transforms->ttMatrix[1][1]*Next->ttMatrix[1][0];
247
248 Int4 = Transforms->ttMatrix[1][0]*Next->ttMatrix[0][1] +
249 Transforms->ttMatrix[1][1]*Next->ttMatrix[1][1];
250
251 Int5 = Transforms->ttMatrix[2][0]*Next->ttMatrix[0][0] +
252 Transforms->ttMatrix[2][1]*Next->ttMatrix[1][0] +
253 Next->ttMatrix[2][0];
254
255 Int6 = Transforms->ttMatrix[2][0]*Next->ttMatrix[0][1] +
256 Transforms->ttMatrix[2][1]*Next->ttMatrix[1][1] +
257 Next->ttMatrix[2][1];
258
259 Transforms->ttMatrix[0][0] = Int1;
260 Transforms->ttMatrix[0][1] = Int2;
261 Transforms->ttMatrix[1][0] = Int3;
262 Transforms->ttMatrix[1][1] = Int4;
263 Transforms->ttMatrix[2][0] = Int5;
264 Transforms->ttMatrix[2][1] = Int6;
265 }
266
267 static long Storage[3][3];
268 static long InverseMatrix[3][3];
269
270 void
TInverse()271 TInverse()
272 {
273 /*
274 Compute the inverse transform of the current transform.
275 Because all transformations are Manhattan, the
276 det of the current transform matrix is always -1 or +1.
277 */
278
279 long Det;
280
281 Det =
282 Transforms->ttMatrix[0][0]*Transforms->ttMatrix[1][1] -
283 Transforms->ttMatrix[1][0]*Transforms->ttMatrix[0][1];
284
285 if (Det == 1) {
286 InverseMatrix[0][0] = Transforms->ttMatrix[1][1];
287 InverseMatrix[0][1] = -Transforms->ttMatrix[0][1];
288 InverseMatrix[1][0] = -Transforms->ttMatrix[1][0];
289 InverseMatrix[1][1] = Transforms->ttMatrix[0][0];
290 InverseMatrix[2][0] =
291 Transforms->ttMatrix[1][0]*Transforms->ttMatrix[2][1] -
292 Transforms->ttMatrix[2][0]*Transforms->ttMatrix[1][1];
293 InverseMatrix[2][1] =
294 - Transforms->ttMatrix[0][0]*Transforms->ttMatrix[2][1] +
295 Transforms->ttMatrix[0][1]*Transforms->ttMatrix[2][0];
296 }
297 else {
298 InverseMatrix[0][0] = -Transforms->ttMatrix[1][1];
299 InverseMatrix[0][1] = Transforms->ttMatrix[0][1];
300 InverseMatrix[1][0] = Transforms->ttMatrix[1][0];
301 InverseMatrix[1][1] = -Transforms->ttMatrix[0][0];
302 InverseMatrix[2][0] =
303 - Transforms->ttMatrix[1][0]*Transforms->ttMatrix[2][1] +
304 Transforms->ttMatrix[2][0]*Transforms->ttMatrix[1][1];
305 InverseMatrix[2][1] =
306 Transforms->ttMatrix[0][0]*Transforms->ttMatrix[2][1] -
307 Transforms->ttMatrix[0][1]*Transforms->ttMatrix[2][0];
308 }
309 InverseMatrix[0][2] = 0;
310 InverseMatrix[1][2] = 0;
311 InverseMatrix[2][2] = 1;
312 }
313
314 void
TInversePoint(X,Y)315 TInversePoint(X,Y)
316 long *X,*Y;
317 {
318 /*
319 Transform the point.
320 */
321 long Int1;
322
323 Int1 = *X*InverseMatrix[0][0] + *Y*InverseMatrix[1][0]
324 + InverseMatrix[2][0];
325 *Y = *X*InverseMatrix[0][1] + *Y*InverseMatrix[1][1]
326 + InverseMatrix[2][1];
327 *X = Int1;
328 }
329
330 void
TStore()331 TStore()
332 {
333 memcpy((char *)Storage,
334 (char *)Transforms->ttMatrix,9*sizeof(long));
335 }
336
337 void
TLoad()338 TLoad()
339 {
340 memcpy((char *)Transforms->ttMatrix,
341 (char *)Storage,9*sizeof(long));
342 }
343
344 void
TLoadInverse()345 TLoadInverse()
346 {
347 memcpy((char *)Transforms->ttMatrix,
348 (char *)InverseMatrix,9*sizeof(long));
349 }
350