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