GRASS Programmer's Manual  6.4.2(2012)
stroke.c
Go to the documentation of this file.
00001 
00002 /****************************************************************************
00003 *
00004 * MODULE:       Symbol library 
00005 *               
00006 * AUTHOR(S):    Radim Blazek
00007 *
00008 * PURPOSE:      Stroke symbol
00009 *
00010 * COPYRIGHT:    (C) 2001 by the GRASS Development Team
00011 *
00012 *               This program is free software under the GNU General Public
00013 *               License (>=v2). Read the file COPYING that comes with GRASS
00014 *               for details.
00015 *
00016 *****************************************************************************/
00017 #include <stdlib.h>
00018 #include <math.h>
00019 #include <grass/gis.h>
00020 #include <grass/symbol.h>
00021 
00022 #define PI M_PI
00023 
00024 void add_coor(SYMBCHAIN * chain, int x, int y)
00025 {
00026     G_debug(5, "    add_coor %d, %d", x, y);
00027     if (chain->scount == chain->salloc) {
00028         chain->salloc += 10;
00029         chain->sx = (int *)G_realloc(chain->sx, chain->salloc * sizeof(int));
00030         chain->sy = (int *)G_realloc(chain->sy, chain->salloc * sizeof(int));
00031     }
00032     chain->sx[chain->scount] = x;
00033     chain->sy[chain->scount] = y;
00034     chain->scount++;
00035 }
00036 
00037 /* draw chain
00038  *   s - scale
00039  *   ch - chain number 
00040  *   rotation - degrees CCW from East
00041  */
00042 int stroke_chain(SYMBPART * part, int ch, double s, double rotation)
00043 {
00044     int k, l, first;
00045     SYMBEL *elem;
00046     SYMBCHAIN *chain;
00047     double r;
00048     double a1, a2, da;
00049     int x, y, x0, y0;
00050 
00051     G_debug(5, "  stroke_chain(): ch = %d", ch);
00052     chain = part->chain[ch];
00053 
00054     G_debug(5, "    element count = %d", chain->count);
00055     first = 1;
00056     for (k = 0; k < chain->count; k++) {
00057         elem = chain->elem[k];
00058         switch (elem->type) {
00059         case S_LINE:
00060             G_debug(5, "    LINE count = %d", elem->coor.line.count);
00061             for (l = 0; l < elem->coor.line.count; l++) {
00062                 x = s * elem->coor.line.x[l];
00063                 y = s * elem->coor.line.y[l];
00064 
00065                 if (rotation != 0.0)
00066                     G_rotate_around_point_int(0, 0, &x, &y, rotation);
00067 
00068                 add_coor(chain, x, y);
00069                 if (first) {
00070                     x0 = x;
00071                     y0 = y;
00072                     first = 0;
00073                 }
00074             }
00075             break;
00076         case S_ARC:
00077             da = 10 * PI / 180; /* later calc from size and tolerance */
00078             r = elem->coor.arc.r;
00079             G_debug(5, "    ARC da = %f r = %f", da, r);
00080 
00081             /* convert to positive angles */
00082             a1 = PI * elem->coor.arc.a1 / 180;
00083             if (a1 < 0)
00084                 a1 += 2 * PI;
00085             a2 = PI * elem->coor.arc.a2 / 180;
00086             if (a2 < 0)
00087                 a2 += 2 * PI;
00088 
00089             if (elem->coor.arc.clock) { /* clockwise */
00090                 while (1) {
00091                     x = s * elem->coor.arc.x + s * r * cos(a1);
00092                     y = s * elem->coor.arc.y + s * r * sin(a1);
00093 
00094                     if (rotation != 0.0)
00095                         G_rotate_around_point_int(0, 0, &x, &y, rotation);
00096 
00097                     add_coor(chain, x, y);
00098                     if (first) {
00099                         x0 = x;
00100                         y0 = y;
00101                         first = 0;
00102                     }
00103                     if (a1 == a2)
00104                         break;
00105                     a1 -= da;
00106                     if (a1 < a2)
00107                         a1 = a2;
00108                 }
00109 
00110             }
00111             else {
00112                 while (1) {
00113                     x = s * elem->coor.arc.x + s * r * cos(a1);
00114                     y = s * elem->coor.arc.y + s * r * sin(a1);
00115 
00116                     if (rotation != 0.0)
00117                         G_rotate_around_point_int(0, 0, &x, &y, rotation);
00118 
00119                     add_coor(chain, x, y);
00120                     if (first) {
00121                         x0 = x;
00122                         y0 = y;
00123                         first = 0;
00124                     }
00125                     if (a1 == a2)
00126                         break;
00127                     a1 += da;
00128                     if (a1 > a2)
00129                         a1 = a2;
00130                 }
00131             }
00132             break;
00133         }
00134     }
00135     if (part->type == S_POLYGON) {
00136         add_coor(chain, x0, y0);        /* Close ring */
00137     }
00138 
00139     return 0;
00140 }
00141 
00142 /* 
00143  *  Stroke symbol to form used for Xdriver.
00144  *
00145  *  tolerance currently not supported
00146  */
00147 void S_stroke(SYMBOL * Symb, int size, double rotation, int tolerance)
00148 {
00149     int i, j;
00150     double s;
00151     SYMBPART *part;
00152 
00153     G_debug(3, "S_stroke(): size = %d rotation = %f tolerance = %d", size,
00154             rotation, tolerance);
00155 
00156     /* TODO: support for tolerance */
00157 
00158     s = size * Symb->scale;
00159 
00160     for (i = 0; i < Symb->count; i++) {
00161         G_debug(4, "  part %d", i);
00162         part = Symb->part[i];
00163         switch (part->type) {
00164         case S_POLYGON:
00165             for (j = 0; j < part->count; j++) { /* RINGS */
00166                 stroke_chain(part, j, s, rotation);
00167             }
00168             break;
00169         case S_STRING:          /* string has 1 chain */
00170             stroke_chain(part, 0, s, rotation);
00171             break;
00172         }
00173     }
00174 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines