1 /* ======================================================= *
2  * Copyright 1998-2005 Stephen C. Grubb                    *
3  * http://ploticus.sourceforge.net                         *
4  * Covered by GPL; see the file ./Copyright for details.   *
5  * ======================================================= */
6 
7 #include "plg.h"
8 
9 #define NVARIAT 18
10 #define NSHAPE 9
11 #define TORAD 0.0174532
12 
13 
14 /* MARK - draw a geometric data point using current line type and current color for line elements. */
15 /* point styles are selected by the code string
16 		"symNS[C]"
17    where	N is an integer 1-9 selecting the shape
18 			(1=up-tri 2=down-tri 3=diam 4=square 5=pent  6=circ  7=right-tri  8=left-tri  9=nice-circle)
19 		S is either 's' for spokes, 'a' for perimeter, or 'n' for no line (fill only)
20 		C is a fill color which may be different from current line color
21 			(if omitted, no filling takes place)
22 
23    Performance is best when point style and radius remains the same for consecutive points.
24 */
25 
26 static char prevcode[40] = "";
27 static double prev_r;
28 static char color[COLORLEN];
29 static int inc, variation;
30 static int nc[] =    {  3,  3,  4,  4,  5, 12, 3, 3, 20 };	/* number of corners (constant) */
31 static int nt[] =    { 90,270,  0, 45, 90, 90, 0, 180, 90 };    /* location (in degrees) of first corner (constant) */
32 static double h[24][2]; /* the offsets */
33 
34 /* ==================================== */
35 int
PLG_mark_initstatic()36 PLG_mark_initstatic()
37 {
38 strcpy( prevcode, "" );
39 return( 0 );
40 }
41 
42 /* ==================================== */
43 int
PLG_mark(x,y,code,r)44 PLG_mark( x, y, code, r )
45 double x, y; 	/* point location in abs space */
46 char code[];	/* pre-set symbol name */
47 double r; 	/* radius of dot in absolute units */
48 {
49 int i;
50 double g, theta;
51 char pixpt_code[30];
52 
53 
54 /* no-op code */
55 if( strcmp( code, "sym00" ) == 0 ) return( 0 );
56 
57 /* gif image as symbol */
58 if( strcmp( code, "img" )==0 ) {
59 	Eimplace( x, y, "", "centered", 0, 0 ); /* 0, 0  means use size set earlier or image's native size */
60 	return( 0 );
61 	}
62 
63 /* pix* or oix* - do a pixpt - added scg 5/25/06 */
64 if( (code[0] == 'p' || code[0] == 'o' ) && code[1] == 'i' && code[2] == 'x' ) {
65 	/* note: radius was embedded in code by symdetails() */
66 	sprintf( pixpt_code, "%s%g", code, r );
67 	Epixpt( x, y, pixpt_code );
68 	return( 0 );
69 	}
70 
71 if( strcmp( code, prevcode ) != 0 || r != prev_r ) {
72 	strcpy( prevcode, code );
73 	prev_r = r;
74 	inc = ((code[3] - '0') -1 ) % NSHAPE;
75 	if( code[4] == '\0' ) code[4] = 'a';
76 	variation = code[4];
77 	if( strlen( code ) > 5 )strcpy( color, &code[5] );
78 	else color[0] = '\0';
79 
80 	theta = 360.0 / (double)nc[inc];
81 	/* get offsets */
82 	g = nt[inc];
83 	for( i = 0; i < nc[inc]; i++ ) {
84 		h[i][0] = r * cos( g * TORAD );
85 		h[i][1] = r * sin( g * TORAD );
86 		g += theta;
87 		}
88 	}
89 /* color point */
90 if( color[0] != '\0' ) {
91 	Emov( x+h[0][0], y+h[0][1] );
92 	for( i = 1; i < nc[inc]; i++ ) Epath( x+h[i][0], y+h[i][1] );
93 	Ecolorfill( color );
94 	}
95 
96 /* draw spokes */
97 if( variation == 's' )
98 	for( i = 0; i < nc[inc]; i++ ) {
99 		Emov( x, y ); Elin( x+h[i][0], y+h[i][1] );
100 		}
101 
102 else if( variation == 'n' ) ;
103 
104 /* draw perimeter */
105 else 	{
106 	Emov( x+h[0][0], y+h[0][1] );
107 	for( i = 1; i < nc[inc]; i++ ) Elin( x+h[i][0], y+h[i][1] );
108 	Elin( x+h[0][0], y+h[0][1] ); /* close to starting point.. */
109 	Elin( x+h[1][0], y+h[1][1] ); /* and do one more so last corner is done right.. */
110 	}
111 
112 return( 0 );
113 }
114 
115 /* ======================================= */
116 /* CIRCLE - draw a circle  */
117 /* added nsides arg - scg 8/17/05 */
118 int
PLG_circle(cx,cy,r,color,outline,nsides)119 PLG_circle( cx, cy, r, color, outline, nsides )
120 double cx, cy; 	/* point location in abs space */
121 double r; 	/* radius of dot in absolute units */
122 char *color;	/* color name, or "" for no fill */
123 int outline;    /* if 1, circle will be outlined. */
124 int nsides;    /* number of sides to draw - max 78 */
125 {
126 double theta, g;
127 int i;
128 static double hx[80], hy[80];
129 static int first = 1;
130 
131 if( first ) {
132 	first = 0;
133 	theta = 360.0 / (double)nsides;
134 	/* get offsets */
135 	g = 0.0;
136 	for( i = 0; i < nsides+1; i++ ) {
137 		hx[i] = cos( (g * TORAD ) );
138 		hy[i] = sin( (g * TORAD ) );
139 		g += theta;
140 		}
141 	}
142 if( color[0] != '\0' ) { /* (was strlen(color) >= 0 ) (?) */
143 	for( i = 0; i < nsides+1; i++ ) {
144 		if( i == 0 ) Emov( cx+(r*hx[i]), cy+(r*hy[i]) );
145 		else Epath( cx+(r*hx[i]), cy+(r*hy[i]) );
146 		}
147 	Ecolorfill( color );
148 	}
149 if( outline ) {
150 	for( i = 0; i < nsides+1; i++ ) {
151 		if( i == 0 ) Emov( cx+(r*hx[i]), cy+(r*hy[i]) );
152 		else Elin( cx+(r*hx[i]), cy+(r*hy[i]) );
153 		}
154 	}
155 return( 0 );
156 }
157 
158 /* ========================================= */
159 /* ELLIPSE  - draw an elipse */
160 int
PLG_ellipse(cx,cy,r1,r2,color,outline)161 PLG_ellipse( cx, cy, r1, r2, color, outline )
162 double cx, cy, r1, r2;
163 char *color;	/* color name, or "" for no fill */
164 int outline;    /* if 1, circle will be outlined. */
165 {
166 double theta, g;
167 int i;
168 static double hx[32], hy[32];
169 int n;
170 
171 n = 25;
172 
173 theta = 360.0 / (double)n;
174 /* get offsets */
175 g = 0.0;
176 for( i = 0; i < n+1; i++ ) {
177         hx[i] = cos( (g * TORAD ) );
178         hy[i] = sin( (g * TORAD ) );
179         g += theta;
180         }
181 
182 if( color[0] != '\0' ) {
183 	for( i = 0; i < n+1; i++ ) {
184        		if( i == 0 ) Emov( cx+(r1*hx[i]), cy+(r2*hy[i]) );
185         	else Epath( cx+(r1*hx[i]), cy+(r2*hy[i]) );
186 		}
187 	Ecolorfill( color );
188         }
189 
190 if( outline ) {
191 	for( i = 0; i < n+1; i++ ) {
192 	        if( i == 0 ) Emov( cx+(r1*hx[i]), cy+(r2*hy[i]) );
193 	        else Elin( cx+(r1*hx[i]), cy+(r2*hy[i]) );
194 	        }
195 	}
196 return( 0 );
197 }
198 
199 /* ======================================================= *
200  * Copyright 1998-2005 Stephen C. Grubb                    *
201  * http://ploticus.sourceforge.net                         *
202  * Covered by GPL; see the file ./Copyright for details.   *
203  * ======================================================= */
204