rubyvor 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,219 @@
1
+
2
+ /*** GEOMETRY.C ***/
3
+
4
+ #include <math.h>
5
+ #include "vdefs.h"
6
+
7
+ static Freelist efl;
8
+
9
+ void
10
+ geominit(void)
11
+ {
12
+ freeinit(&efl, sizeof(Edge)) ;
13
+ rubyvorState.nvertices = rubyvorState.nedges = 0 ;
14
+ rubyvorState.sqrt_nsites = sqrt(rubyvorState.nsites+4) ;
15
+ rubyvorState.deltay = rubyvorState.ymax - rubyvorState.ymin ;
16
+ rubyvorState.deltax = rubyvorState.xmax - rubyvorState.xmin ;
17
+ }
18
+
19
+ Edge *
20
+ bisect(Site * s1, Site * s2)
21
+ {
22
+ float dx, dy, adx, ady ;
23
+ Edge * newedge ;
24
+
25
+ newedge = (Edge *)getfree(&efl) ;
26
+ newedge->reg[0] = s1 ;
27
+ newedge->reg[1] = s2 ;
28
+ ref(s1) ;
29
+ ref(s2) ;
30
+ newedge->ep[0] = newedge->ep[1] = (Site *)NULL ;
31
+ dx = s2->coord.x - s1->coord.x ;
32
+ dy = s2->coord.y - s1->coord.y ;
33
+ adx = dx>0 ? dx : -dx ;
34
+ ady = dy>0 ? dy : -dy ;
35
+ newedge->c = s1->coord.x * dx + s1->coord.y * dy + (dx*dx +
36
+ dy*dy) * 0.5 ;
37
+ if (adx > ady)
38
+ {
39
+ newedge->a = 1.0 ;
40
+ newedge->b = dy/dx ;
41
+ newedge->c /= dx ;
42
+ }
43
+ else
44
+ {
45
+ newedge->b = 1.0 ;
46
+ newedge->a = dx/dy ;
47
+ newedge->c /= dy ;
48
+ }
49
+ newedge->edgenbr = rubyvorState.nedges ;
50
+ out_bisector(newedge) ;
51
+ rubyvorState.nedges++ ;
52
+ return (newedge) ;
53
+ }
54
+
55
+ Site *
56
+ intersect(Halfedge * el1, Halfedge * el2)
57
+ {
58
+ Edge * e1, * e2, * e ;
59
+ Halfedge * el ;
60
+ float d, xint, yint ;
61
+ int right_of_site ;
62
+ Site * v ;
63
+
64
+ e1 = el1->ELedge ;
65
+ e2 = el2->ELedge ;
66
+ if ((e1 == (Edge*)NULL) || (e2 == (Edge*)NULL))
67
+ {
68
+ return ((Site *)NULL) ;
69
+ }
70
+ if (e1->reg[1] == e2->reg[1])
71
+ {
72
+ return ((Site *)NULL) ;
73
+ }
74
+ d = (e1->a * e2->b) - (e1->b * e2->a) ;
75
+ if ((-1.0e-10 < d) && (d < 1.0e-10))
76
+ {
77
+ return ((Site *)NULL) ;
78
+ }
79
+ xint = (e1->c * e2->b - e2->c * e1->b) / d ;
80
+ yint = (e2->c * e1->a - e1->c * e2->a) / d ;
81
+ if ((e1->reg[1]->coord.y < e2->reg[1]->coord.y) ||
82
+ (e1->reg[1]->coord.y == e2->reg[1]->coord.y &&
83
+ e1->reg[1]->coord.x < e2->reg[1]->coord.x))
84
+ {
85
+ el = el1 ;
86
+ e = e1 ;
87
+ }
88
+ else
89
+ {
90
+ el = el2 ;
91
+ e = e2 ;
92
+ }
93
+ right_of_site = (xint >= e->reg[1]->coord.x) ;
94
+ if ((right_of_site && (el->ELpm == le)) ||
95
+ (!right_of_site && (el->ELpm == re)))
96
+ {
97
+ return ((Site *)NULL) ;
98
+ }
99
+ v = (Site *)getfree(&(rubyvorState.sfl)) ;
100
+ v->refcnt = 0 ;
101
+ v->coord.x = xint ;
102
+ v->coord.y = yint ;
103
+ return (v) ;
104
+ }
105
+
106
+ /*** returns 1 if p is to right of halfedge e ***/
107
+
108
+ int
109
+ right_of(Halfedge * el, Point * p)
110
+ {
111
+ Edge * e ;
112
+ Site * topsite ;
113
+ int right_of_site, above, fast ;
114
+ float dxp, dyp, dxs, t1, t2, t3, yl ;
115
+
116
+ e = el->ELedge ;
117
+ topsite = e->reg[1] ;
118
+ right_of_site = (p->x > topsite->coord.x) ;
119
+ if (right_of_site && (el->ELpm == le))
120
+ {
121
+ return (1) ;
122
+ }
123
+ if(!right_of_site && (el->ELpm == re))
124
+ {
125
+ return (0) ;
126
+ }
127
+ if (e->a == 1.0)
128
+ {
129
+ dyp = p->y - topsite->coord.y ;
130
+ dxp = p->x - topsite->coord.x ;
131
+ fast = 0 ;
132
+ if ((!right_of_site & (e->b < 0.0)) ||
133
+ (right_of_site & (e->b >= 0.0)))
134
+ {
135
+ fast = above = (dyp >= e->b*dxp) ;
136
+ }
137
+ else
138
+ {
139
+ above = ((p->x + p->y * e->b) > (e->c)) ;
140
+ if (e->b < 0.0)
141
+ {
142
+ above = !above ;
143
+ }
144
+ if (!above)
145
+ {
146
+ fast = 1 ;
147
+ }
148
+ }
149
+ if (!fast)
150
+ {
151
+ dxs = topsite->coord.x - (e->reg[0])->coord.x ;
152
+ above = (e->b * (dxp*dxp - dyp*dyp))
153
+ <
154
+ (dxs * dyp * (1.0 + 2.0 * dxp /
155
+ dxs + e->b * e->b)) ;
156
+ if (e->b < 0.0)
157
+ {
158
+ above = !above ;
159
+ }
160
+ }
161
+ }
162
+ else /*** e->b == 1.0 ***/
163
+ {
164
+ yl = e->c - e->a * p->x ;
165
+ t1 = p->y - yl ;
166
+ t2 = p->x - topsite->coord.x ;
167
+ t3 = yl - topsite->coord.y ;
168
+ above = ((t1*t1) > ((t2 * t2) + (t3 * t3))) ;
169
+ }
170
+ return (el->ELpm == le ? above : !above) ;
171
+ }
172
+
173
+ void
174
+ endpoint(Edge * e, int lr, Site * s)
175
+ {
176
+ e->ep[lr] = s ;
177
+ ref(s) ;
178
+ if (e->ep[re-lr] == (Site *)NULL)
179
+ {
180
+ return ;
181
+ }
182
+ out_ep(e) ;
183
+ deref(e->reg[le]) ;
184
+ deref(e->reg[re]) ;
185
+ makefree((Freenode *)e, (Freelist *) &efl) ;
186
+ }
187
+
188
+ float
189
+ dist(Site * s, Site * t)
190
+ {
191
+ float dx,dy ;
192
+
193
+ dx = s->coord.x - t->coord.x ;
194
+ dy = s->coord.y - t->coord.y ;
195
+ return (sqrt(dx*dx + dy*dy)) ;
196
+ }
197
+
198
+ void
199
+ makevertex(Site * v)
200
+ {
201
+ v->sitenbr = rubyvorState.nvertices++ ;
202
+ out_vertex(v) ;
203
+ }
204
+
205
+ void
206
+ deref(Site * v)
207
+ {
208
+ if (--(v->refcnt) == 0 )
209
+ {
210
+ makefree((Freenode *)v, (Freelist *)&(rubyvorState.sfl)) ;
211
+ }
212
+ }
213
+
214
+ void
215
+ ref(Site * v)
216
+ {
217
+ ++(v->refcnt) ;
218
+ }
219
+
@@ -0,0 +1,118 @@
1
+
2
+ /*** HEAP.C ***/
3
+
4
+
5
+ #include "vdefs.h"
6
+
7
+ static int PQmin, PQcount, PQhashsize ;
8
+ static Halfedge * PQhash ;
9
+
10
+ void
11
+ PQinsert(Halfedge * he, Site * v, float offset)
12
+ {
13
+ Halfedge * last, * next ;
14
+
15
+ he->vertex = v ;
16
+ ref(v) ;
17
+ he->ystar = v->coord.y + offset ;
18
+ last = &PQhash[ PQbucket(he)] ;
19
+ while ((next = last->PQnext) != (Halfedge *)NULL &&
20
+ (he->ystar > next->ystar ||
21
+ (he->ystar == next->ystar &&
22
+ v->coord.x > next->vertex->coord.x)))
23
+ {
24
+ last = next ;
25
+ }
26
+ he->PQnext = last->PQnext ;
27
+ last->PQnext = he ;
28
+ PQcount++ ;
29
+ }
30
+
31
+ void
32
+ PQdelete(Halfedge * he)
33
+ {
34
+ Halfedge * last;
35
+
36
+ if(he -> vertex != (Site *) NULL)
37
+ {
38
+ last = &PQhash[PQbucket(he)] ;
39
+ while (last -> PQnext != he)
40
+ {
41
+ last = last->PQnext ;
42
+ }
43
+ last->PQnext = he->PQnext;
44
+ PQcount-- ;
45
+ deref(he->vertex) ;
46
+ he->vertex = (Site *)NULL ;
47
+ }
48
+ }
49
+
50
+ int
51
+ PQbucket(Halfedge * he)
52
+ {
53
+ int bucket ;
54
+
55
+
56
+ if (he->ystar < rubyvorState.ymin) bucket = 0;
57
+ else if (he->ystar >= rubyvorState.ymax) bucket = PQhashsize-1;
58
+ else bucket = (he->ystar - rubyvorState.ymin)/rubyvorState.deltay * PQhashsize;
59
+ if (bucket < 0)
60
+ {
61
+ bucket = 0 ;
62
+ }
63
+ if (bucket >= PQhashsize)
64
+ {
65
+ bucket = PQhashsize-1 ;
66
+ }
67
+ if (bucket < PQmin)
68
+ {
69
+ PQmin = bucket ;
70
+ }
71
+ return (bucket);
72
+ }
73
+
74
+ int
75
+ PQempty(void)
76
+ {
77
+ return (PQcount == 0) ;
78
+ }
79
+
80
+
81
+ Point
82
+ PQ_min(void)
83
+ {
84
+ Point answer ;
85
+
86
+ while (PQhash[PQmin].PQnext == (Halfedge *)NULL)
87
+ {
88
+ ++PQmin ;
89
+ }
90
+ answer.x = PQhash[PQmin].PQnext->vertex->coord.x ;
91
+ answer.y = PQhash[PQmin].PQnext->ystar ;
92
+ return (answer) ;
93
+ }
94
+
95
+ Halfedge *
96
+ PQextractmin(void)
97
+ {
98
+ Halfedge * curr ;
99
+
100
+ curr = PQhash[PQmin].PQnext ;
101
+ PQhash[PQmin].PQnext = curr->PQnext ;
102
+ PQcount-- ;
103
+ return (curr) ;
104
+ }
105
+
106
+ void
107
+ PQinitialize(void)
108
+ {
109
+ int i ;
110
+
111
+ PQcount = PQmin = 0 ;
112
+ PQhashsize = 4 * rubyvorState.sqrt_nsites ;
113
+ PQhash = (Halfedge *)myalloc(PQhashsize * sizeof *PQhash) ;
114
+ for (i = 0 ; i < PQhashsize; i++)
115
+ {
116
+ PQhash[i].PQnext = (Halfedge *)NULL ;
117
+ }
118
+ }
@@ -0,0 +1,118 @@
1
+
2
+ /*** MEMORY.C ***/
3
+
4
+ #include <ruby.h>
5
+ #include <stdio.h>
6
+ #include <stdlib.h> /* malloc() */
7
+
8
+ #include "vdefs.h"
9
+
10
+ static char** memory_map;
11
+ static int nallocs = 0;
12
+
13
+ void
14
+ freeinit(Freelist * fl, int size)
15
+ {
16
+ fl->head = (Freenode *)NULL ;
17
+ fl->nodesize = size ;
18
+ }
19
+
20
+ char *
21
+ getfree(Freelist * fl)
22
+ {
23
+ int i ;
24
+ Freenode * t ;
25
+ if (fl->head == (Freenode *)NULL)
26
+ {
27
+ t = (Freenode *) myalloc(rubyvorState.sqrt_nsites * fl->nodesize) ;
28
+ for(i = 0 ; i < rubyvorState.sqrt_nsites ; i++)
29
+ {
30
+ makefree((Freenode *)((char *)t+i*fl->nodesize), fl) ;
31
+ }
32
+ }
33
+ t = fl->head ;
34
+ fl->head = (fl->head)->nextfree ;
35
+ return ((char *)t) ;
36
+ }
37
+
38
+ void
39
+ makefree(Freenode * curr, Freelist * fl)
40
+ {
41
+ curr->nextfree = fl->head ;
42
+ fl->head = curr ;
43
+ }
44
+
45
+ int total_alloc;
46
+
47
+ void
48
+ update_memory_map(char * newp)
49
+ {
50
+ if (nallocs % 1000 == 0)
51
+ {
52
+ if (nallocs == 0)
53
+ memory_map = (char **)malloc((nallocs+1000)*sizeof(char*));
54
+ else
55
+ memory_map = (char **)realloc(memory_map,(nallocs+1000)*sizeof(char*));
56
+ }
57
+ memory_map[nallocs++] = newp;
58
+ }
59
+
60
+ char *
61
+ myalloc(unsigned n)
62
+ {
63
+ char * t;
64
+
65
+ if ((t=(char*)malloc(n)) == (char *) 0)
66
+ rb_raise(rb_eNoMemError, "Insufficient memory processing site %d (%d bytes in use)\n", rubyvorState.siteidx, total_alloc);
67
+
68
+ total_alloc += n;
69
+
70
+ update_memory_map(t);
71
+ return (t);
72
+ }
73
+
74
+ char *
75
+ myrealloc(void * oldp, unsigned n, unsigned oldn)
76
+ {
77
+ char * newp;
78
+ int i;
79
+
80
+ if ((newp=(char*)realloc(oldp, n)) == (char *) 0)
81
+ rb_raise(rb_eNoMemError, "Insufficient memory processing site %d (%d bytes in use)\n", rubyvorState.siteidx, total_alloc);
82
+
83
+ total_alloc += (n - oldn);
84
+
85
+ update_memory_map(newp);
86
+
87
+ /*
88
+ * Mark oldp as freed, since free() was called by realloc.
89
+ *
90
+ * TODO: this seems naive; measure if this is a bottleneck & use a hash table or some other scheme if it is.
91
+ */
92
+ for (i=0; i<nallocs; i++)
93
+ {
94
+ if (memory_map[i] != (char*)0 && memory_map[i] == oldp)
95
+ {
96
+ memory_map[i] = (char*)0;
97
+ break;
98
+ }
99
+ }
100
+
101
+ return (newp);
102
+ }
103
+
104
+
105
+ void free_all(void)
106
+ {
107
+ int i;
108
+ for (i=0; i<nallocs; i++)
109
+ {
110
+ if (memory_map[i] != (char*)0)
111
+ {
112
+ free(memory_map[i]);
113
+ memory_map[i] = (char*)0;
114
+ }
115
+ }
116
+ free(memory_map);
117
+ nallocs = 0;
118
+ }