2
* Grace - Graphics for Exploratory Data Analysis
4
* Home page: http://plasma-gate.weizmann.ac.il/Grace/
6
* Copyright (c) 1991-1995 Paul J Turner, Portland, OR
7
* Copyright (c) 1996-2001 Grace Development Team
9
* Maintained by Evgeny Stambulchik <fnevgeny@plasma-gate.weizmann.ac.il>
14
* This program is free software; you can redistribute it and/or modify
15
* it under the terms of the GNU General Public License as published by
16
* the Free Software Foundation; either version 2 of the License, or
17
* (at your option) any later version.
19
* This program is distributed in the hope that it will be useful,
20
* but WITHOUT ANY WARRANTY; without even the implied warranty of
21
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
* GNU General Public License for more details.
24
* You should have received a copy of the GNU General Public License
25
* along with this program; if not, write to the Free Software
26
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31
* routines to allocate, manipulate, and return
32
* information about regions.
51
* see if (x,y) lies inside the plot
53
int inbounds(int gno, double x, double y)
59
return is_validWPoint(wp);
62
int isactive_region(int regno)
64
return (regno == MAXREGION || regno == MAXREGION + 1 || rg[regno].active == TRUE);
67
char *region_types(int it, int which)
116
void kill_region(int r)
121
rg[r].active = FALSE;
127
void kill_all_regions(void)
130
for (r = 0; r < MAXREGION; r++) {
135
void activate_region(int r, int type, int linkto)
140
rg[r].linkto = linkto;
146
* report on sets in a region
148
void reporton_region(int gno, int rno, int type)
151
int i, j, first, contained;
153
sprintf(buf, "\nRegion R%1d contains:\n", rno);
155
for (j = 0; j < number_of_sets(gno); j++) {
156
if (is_set_active(gno, j)) {
161
for (i = 0; i < getsetlength(gno, j); i++) {
162
if (inregion(rno, x[i], y[i])) {
165
case 0: /* report on sets */
168
sprintf(buf, " Set S%1d\n", j);
175
sprintf(buf, " Set S%1d\n", j);
178
sprintf(buf, " %d %f %f\n", i + 1, x[i], y[i]);
191
void load_poly_region(int r, int gno, int n, WPoint *wps)
196
activate_region(r, regiontype, gno);
198
rg[r].x = xcalloc(n, SIZEOF_DOUBLE);
199
rg[r].y = xcalloc(n, SIZEOF_DOUBLE);
200
for (i = 0; i < n; i++) {
201
rg[r].x[i] = wps[i].x;
202
rg[r].y[i] = wps[i].y;
208
* routines to determine if a point lies in a polygon
210
int intersect_to_left(double x, double y, double x1, double y1, double x2, double y2)
214
/* ignore horizontal lines */
218
/* not contained vertically */
219
if (((y < y1) && (y < y2)) || ((y > y1) && (y > y2))) {
222
/* none of the above, compute the intersection */
223
if ((xtmp = x2 - x1) != 0.0) {
224
m = (y2 - y1) / xtmp;
231
/* check for intersections at a vertex */
232
/* if this is the max ordinate then accept */
240
/* check for intersections at a vertex */
248
/* no vertices intersected */
255
* determine if (x,y) is in the polygon xlist[], ylist[]
257
int inbound(double x, double y, double *xlist, double *ylist, int n)
261
for (i = 0; i < n; i++) {
262
l += intersect_to_left(x, y, xlist[i], ylist[i], xlist[(i + 1) % n], ylist[(i + 1) % n]);
268
* routines to determine if a point lies to the left of an infinite line
270
int isleft(double x, double y, double x1, double y1, double x2, double y2)
274
/* horizontal lines */
278
/* none of the above, compute the intersection */
279
if ((xtmp = x2 - x1) != 0.0) {
280
m = (y2 - y1) / xtmp;
294
* routines to determine if a point lies to the left of an infinite line
296
int isright(double x, double y, double x1, double y1, double x2, double y2)
300
/* horizontal lines */
304
if ((xtmp = x2 - x1) != 0.0) {
305
m = (y2 - y1) / xtmp;
318
* routines to determine if a point lies above an infinite line
320
int isabove(double x, double y, double x1, double y1, double x2, double y2)
328
if ((ytmp = y2 - y1) != 0.0) {
329
m = ytmp / (x2 - x1);
342
* routines to determine if a point lies below an infinite line
344
int isbelow(double x, double y, double x1, double y1, double x2, double y2)
352
if ((ytmp = y2 - y1) != 0.0) {
353
m = ytmp / (x2 - x1);
365
int inregion(int regno, double x, double y)
367
if (regno == MAXREGION) {
368
return (inbounds(get_cg() , x, y));
370
if (regno == MAXREGION + 1) {
371
return (!inbounds(get_cg() , x, y));
373
if (rg[regno].active == TRUE) {
374
switch (rg[regno].type) {
376
if (inbound(x, y, rg[regno].x, rg[regno].y, rg[regno].n)) {
381
if (!inbound(x, y, rg[regno].x, rg[regno].y, rg[regno].n)) {
386
if (isright(x, y, rg[regno].x1, rg[regno].y1, rg[regno].x2, rg[regno].y2)) {
391
if (isleft(x, y, rg[regno].x1, rg[regno].y1, rg[regno].x2, rg[regno].y2)) {
396
if (isabove(x, y, rg[regno].x1, rg[regno].y1, rg[regno].x2, rg[regno].y2)) {
401
if (isbelow(x, y, rg[regno].x1, rg[regno].y1, rg[regno].x2, rg[regno].y2)) {
406
return (x >= rg[regno].x1) && ( x <= rg[regno].x2);
409
return (y >= rg[regno].y1) && ( y <= rg[regno].y2);
412
return !( (x >= rg[regno].x1) && ( x <= rg[regno].x2) );
415
return !( (y >= rg[regno].y1) && ( y <= rg[regno].y2) );