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