1 /*
2 * Eukleides version 1.5.4
3 * Copyright (c) Christian Obrecht 2004-2010
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include <stdlib.h>
21 #include <math.h>
22 #include "error.h"
23 #include "symbol.h"
24 #include "core.h"
25 #include "utils.h"
26
27 #define STO(addr) (POP(_symbol))->content->value.point = (addr)
28
29 double l, m, x, y, u, v;
30
31 _point *A, *B, *C, *D;
32
assign(int p,int s)33 void assign(int p, int s)
34 {
35 if (p < 3) {
36 switch(p) {
37 case 0: get_mem(A, _point);
38 A->x = 0;
39 A->y = 0;
40 STO(A);
41 get_mem(B, _point);
42 B->x = l*x;
43 B->y = l*y;
44 STO(B);
45 break;
46 case 1: A = POP(_point);
47 get_mem(B, _point);
48 B->x = A->x + l*x;
49 B->y = A->y + l*y;
50 STO(B);
51 break;
52 case 2: A = POP(_point);
53 B = POP(_point);
54 l = distance(A, B);
55 if (ZERO(l)) runtime_error(_("invalid points"));
56 x = (B->x - A->x)/l;
57 y = (B->y - A->y)/l;
58 }
59 if (s == 1) m = l;
60 get_mem(C, _point);
61 C->x = B->x + m*(u*x - v*y);
62 C->y = B->y + m*(v*x + u*y);
63 STO(C);
64 } else {
65 A = POP(_point);
66 B = POP(_point);
67 C = POP(_point);
68 }
69 get_mem(D, _point);
70 D->x = A->x + C->x - B->x;
71 D->y = A->y + C->y - B->y;
72 STO(D);
73 }
74
define_parallelogram_SSA(_param p)75 void define_parallelogram_SSA(_param p)
76 {
77 double a, b;
78
79 if (p.addr < 2) {
80 b = POPn;
81 a = POPn;
82 m = POPn;
83 l = POPn;
84 x = Cos(b);
85 y = Sin(b);
86 u = Cos(a);
87 v = Sin(a);
88 } else if (p.addr == 2) {
89 a = POPn;
90 m = POPn;
91 u = Cos(a);
92 v = Sin(a);
93 }
94 assign(p.addr, 0);
95 }
96
define_parallelogram_VV(_param p)97 void define_parallelogram_VV(_param p)
98 {
99 _vector *u, *v;
100
101 v = POP(_vector);
102 u = POP(_vector);
103 if (p.addr == 0) {
104 get_mem(A, _point);
105 A->x = 0;
106 A->y = 0;
107 STO(A);
108 } else A = POP(_point);
109 get_mem(B, _point);
110 B->x = A->x + u->x;
111 B->y = A->y + u->y;
112 STO(B);
113 get_mem(C, _point);
114 C->x = A->x + u->x + v->x;
115 C->y = A->y + u->y + v->y;
116 STO(C);
117 get_mem(D, _point);
118 D->x = A->x + v->x;
119 D->y = A->y + v->y;
120 STO(D);
121 }
122
define_rectangle(_param p)123 void define_rectangle(_param p)
124 {
125 double b;
126
127 if (p.addr < 2) {
128 b = POPn;
129 m = POPn;
130 l = POPn;
131 x = Cos(b);
132 y = Sin(b);
133 } else m = POPn;
134 u = 0;
135 v = 1;
136 assign(p.addr, 0);
137 }
138
define_square(_param p)139 void define_square(_param p)
140 {
141 double b;
142
143 if (p.addr < 2) {
144 b = POPn;
145 l = POPn;
146 x = Cos(b);
147 y = Sin(b);
148 }
149 u = 0;
150 v = 1;
151 assign(p.addr, 1);
152 }
153