libgeda

o_arc_basic.c

Go to the documentation of this file.
00001 /* gEDA - GPL Electronic Design Automation
00002  * libgeda - gEDA's library
00003  * Copyright (C) 1998-2010 Ales Hvezda
00004  * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00019  */
00020 
00025 #include <config.h>
00026 
00027 #include <stdio.h>
00028 #include <math.h>
00029 
00030 #include "libgeda_priv.h"
00031 
00032 #ifdef HAVE_LIBDMALLOC
00033 #include <dmalloc.h>
00034 #endif
00035 
00064 OBJECT *o_arc_new(TOPLEVEL *toplevel,
00065           char type, int color,
00066           int x, int y, int radius, int start_angle, int end_angle)
00067 {
00068 
00069   OBJECT *new_node;
00070 
00071   new_node = s_basic_new_object(type, "arc");
00072 
00073   new_node->color = color;
00074 
00075   new_node->arc = (ARC *) g_malloc(sizeof(ARC));
00076 
00085   /* World coordinates */
00086   new_node->arc->x      = x; 
00087   new_node->arc->y      = y; 
00088   new_node->arc->width  = 2 * radius;
00089   new_node->arc->height = 2 * radius;
00090 
00091   /* must check the sign of start_angle, end_angle ... */
00092   if(end_angle < 0) {
00093     start_angle = start_angle + end_angle;
00094     end_angle = -end_angle;
00095   }
00096   if(start_angle < 0) start_angle = 360 + start_angle;
00097   
00098   new_node->arc->start_angle = start_angle;
00099   new_node->arc->end_angle   = end_angle;
00100 
00101   /* Default init */
00102   o_set_line_options(toplevel, new_node,
00103                      END_NONE, TYPE_SOLID, 0, -1, -1);
00104   o_set_fill_options(toplevel, new_node,
00105                      FILLING_HOLLOW, -1, -1, -1, -1, -1);
00106     
00107   o_arc_recalc(toplevel, new_node);
00108 
00109   /* new_node->graphical = arc; eventually */
00110 
00111   return new_node;
00112 }
00113 
00127 OBJECT *o_arc_copy(TOPLEVEL *toplevel, OBJECT *o_current)
00128 {
00129   OBJECT *new_obj;
00130 
00131   new_obj = o_arc_new (toplevel, OBJ_ARC, o_current->color,
00132                        o_current->arc->x, o_current->arc->y,
00133                        o_current->arc->width / 2,
00134                        o_current->arc->start_angle,
00135                        o_current->arc->end_angle);
00136   o_set_line_options(toplevel, new_obj,
00137                      o_current->line_end, o_current->line_type,
00138                      o_current->line_width,
00139                      o_current->line_length, o_current->line_space);
00140   o_set_fill_options(toplevel, new_obj,
00141                      FILLING_HOLLOW, -1, -1, -1, -1, -1);
00142 
00143   return new_obj;
00144 }
00145 
00171 void o_arc_modify(TOPLEVEL *toplevel, OBJECT *object,
00172           int x, int y, int whichone)
00173 {
00174 
00175     o_emit_pre_change_notify (toplevel, object);
00176 
00177     switch(whichone) {
00178         case ARC_CENTER:
00179         /* modify the center of arc object */
00180         object->arc->x = x;
00181         object->arc->y = y;
00182         break;
00183         
00184         case ARC_RADIUS:
00185         /* modify the radius of arc object */
00186         object->arc->width  = 2 * x;
00187         object->arc->height = 2 * x;
00188         break;
00189 
00190         case ARC_START_ANGLE:
00191         /* modify the start angle of the arc object */
00192         object->arc->start_angle = x;
00193         break;
00194 
00195         case ARC_END_ANGLE:
00196         /* modify the end angle of the arc object */
00197         object->arc->end_angle = x;
00198         break;
00199 
00200         default:
00201         break;
00202     }
00203 
00204     /* update the screen coords and the bounding box */
00205     o_arc_recalc(toplevel, object);
00206     o_emit_change_notify (toplevel, object);
00207 }
00208 
00235 OBJECT *o_arc_read (TOPLEVEL *toplevel, const char buf[],
00236            unsigned int release_ver, unsigned int fileformat_ver, GError **err)
00237 {
00238   OBJECT *new_obj;
00239   char type; 
00240   int x1, y1;
00241   int radius;
00242   int start_angle, end_angle;
00243   int color;
00244   int arc_width, arc_length, arc_space;
00245   int arc_type;
00246   int arc_end;
00247 
00253   if(release_ver <= VERSION_20000704) {
00254     if (sscanf(buf, "%c %d %d %d %d %d %d", &type,
00255            &x1, &y1, &radius, &start_angle, &end_angle, &color) != 7) {
00256       g_set_error (err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse arc object"));
00257       return NULL;
00258     }
00259 
00260     arc_width = 0;
00261     arc_end   = END_NONE;
00262     arc_type  = TYPE_SOLID;
00263     arc_space = -1;
00264     arc_length= -1;
00265   } else {
00266     if (sscanf(buf, "%c %d %d %d %d %d %d %d %d %d %d %d", &type,
00267            &x1, &y1, &radius, &start_angle, &end_angle, &color,
00268            &arc_width, &arc_end, &arc_type, &arc_length, &arc_space) != 12) {
00269       g_set_error (err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse arc object"));
00270       return NULL;
00271     }
00272   }
00273 
00274   /* Error check */
00275   if (radius <= 0) {
00276     s_log_message (_("Found a zero radius arc [ %c %d, %d, %d, %d, %d, %d ]\n"),
00277                    type, x1, y1, radius, start_angle, end_angle, color);
00278     radius = 0;
00279   }
00280     
00281   if (color < 0 || color > MAX_COLORS) {
00282     s_log_message(_("Found an invalid color [ %s ]\n"), buf);
00283     s_log_message(_("Setting color to default color\n"));
00284     color = DEFAULT_COLOR;
00285   }
00286 
00287   /* Allocation and initialization */
00288   new_obj = o_arc_new(toplevel, OBJ_ARC, color,
00289                       x1, y1, radius, start_angle, end_angle);
00290   o_set_line_options(toplevel, new_obj,
00291                      arc_end, arc_type, arc_width, arc_length,
00292                      arc_space);
00293   o_set_fill_options(toplevel, new_obj,
00294                      FILLING_HOLLOW, -1, -1, -1,
00295                      -1, -1);
00296 
00297   return new_obj;
00298 }
00299 
00311 char *o_arc_save(TOPLEVEL *toplevel, OBJECT *object)
00312 {
00313   int x, y, radius, start_angle, end_angle;
00314   int arc_width, arc_length, arc_space;
00315   char *buf;
00316   OBJECT_END arc_end;
00317   OBJECT_TYPE arc_type;
00318 
00319   /* radius, center and angles of the arc */
00320   radius      = object->arc->width / 2;
00321   x           = object->arc->x;
00322   y           = object->arc->y;
00323   start_angle = object->arc->start_angle;
00324   end_angle   = object->arc->end_angle;
00325 
00326   /* line type parameters */
00327   arc_width  = object->line_width;
00328   arc_end    = object->line_end;
00329   arc_type   = object->line_type;
00330   arc_length = object->line_length;
00331   arc_space  = object->line_space;
00332 
00333   /* Describe a circle with post-20000704 file format */
00334   buf = g_strdup_printf("%c %d %d %d %d %d %d %d %d %d %d %d", object->type,
00335             x, y, radius, start_angle, end_angle, object->color,
00336             arc_width, arc_end, arc_type, arc_length, arc_space);
00337 
00338   return(buf);
00339 }
00340 
00351 void o_arc_translate_world(TOPLEVEL *toplevel, int dx, int dy,
00352                OBJECT *object)
00353 {
00354   if (object == NULL) {
00355     return;
00356   }
00357 
00358   /* Do world coords */
00359   object->arc->x = object->arc->x + dx;
00360   object->arc->y = object->arc->y + dy;
00361 
00362 
00363   /* Recalculate screen coords from new world coords */
00364   o_arc_recalc(toplevel, object);
00365 }
00366 
00387 void o_arc_rotate_world(TOPLEVEL *toplevel,
00388             int world_centerx, int world_centery, int angle,
00389             OBJECT *object)
00390 {
00391   int x, y, newx, newy;
00392 
00393   /* translate object to origin */
00394   object->arc->x -= world_centerx;
00395   object->arc->y -= world_centery;
00396 
00397   /* get center, and rotate center */
00398   x = object->arc->x;
00399   y = object->arc->y;
00400   if(angle % 90 == 0) {
00401       rotate_point_90(x, y, angle % 360, &newx, &newy);
00402   } else {
00403       rotate_point(x, y, angle % 360, &newx, &newy);
00404   }
00405   object->arc->x = newx;
00406   object->arc->y = newy;
00407 
00408   /* apply rotation to angles */
00409   object->arc->start_angle = (object->arc->start_angle + angle) % 360;
00410   /* end_angle is unchanged as it is the sweep of the arc */
00411   /* object->arc->end_angle = (object->arc->end_angle); */
00412 
00413   /* translate object to its previous place */
00414   object->arc->x += world_centerx;
00415   object->arc->y += world_centery;
00416 
00417   /* update the screen coords and the bounding box */
00418   o_arc_recalc(toplevel, object);
00419   
00420 }                                   
00421 
00438 void o_arc_mirror_world(TOPLEVEL *toplevel,
00439             int world_centerx, int world_centery,
00440             OBJECT *object)
00441 {
00442   /* translate object to origin */
00443   object->arc->x -= world_centerx;
00444   object->arc->y -= world_centery;
00445 
00446   /* get center, and mirror it (vertical mirror) */
00447   object->arc->x = -object->arc->x;
00448   object->arc->y =  object->arc->y;
00449 
00450   /* apply mirror to angles (vertical mirror) */
00451   object->arc->start_angle = (180 - object->arc->start_angle) % 360;
00452   /* start_angle *MUST* be positive */
00453   if(object->arc->start_angle < 0) object->arc->start_angle += 360;
00454   object->arc->end_angle = -object->arc->end_angle;
00455     
00456   /* translate object back to its previous position */
00457   object->arc->x += world_centerx;
00458   object->arc->y += world_centery;
00459 
00460   /* update the screen coords and bounding box */
00461   o_arc_recalc(toplevel, object);
00462     
00463 }
00464 
00478 void o_arc_recalc(TOPLEVEL *toplevel, OBJECT *o_current)
00479 {
00480   int left, right, top, bottom;
00481     
00482   if (o_current->arc == NULL) {
00483     return;
00484   }
00485 
00486   /* recalculates the bounding box */
00487   world_get_arc_bounds(toplevel, o_current, &left, &top, &right, &bottom);
00488   o_current->w_left   = left;
00489   o_current->w_top    = top;
00490   o_current->w_right  = right;
00491   o_current->w_bottom = bottom;
00492   o_current->w_bounds_valid = TRUE;
00493 }
00494 
00495 
00514 void world_get_arc_bounds(TOPLEVEL *toplevel, OBJECT *object, int *left,
00515               int *top, int *right, int *bottom)
00516 {
00517   int x1, y1, x2, y2, x3, y3;
00518   int radius, start_angle, end_angle;
00519   int i, angle;
00520   int halfwidth;
00521 
00522   halfwidth = object->line_width / 2;
00523 
00524   radius      = object->arc->width / 2;
00525   start_angle = object->arc->start_angle;
00526   end_angle   = object->arc->end_angle;
00527 
00528   x1 = object->arc->x;
00529   y1 = object->arc->y;
00530   x2 = x1 + radius * cos(start_angle * M_PI / 180);
00531   y2 = y1 + radius * sin(start_angle * M_PI / 180);
00532   x3 = x1 + radius * cos((start_angle + end_angle) * M_PI / 180);
00533   y3 = y1 + radius * sin((start_angle + end_angle) * M_PI / 180);
00534 
00535   *left   = (x1 < x2) ? ((x1 < x3) ? x1 : x3) : ((x2 < x3) ? x2 : x3);
00536   *right  = (x1 > x2) ? ((x1 > x3) ? x1 : x3) : ((x2 > x3) ? x2 : x3);
00537   *bottom = (y1 > y2) ? ((y1 > y3) ? y1 : y3) : ((y2 > y3) ? y2 : y3);
00538   *top    = (y1 < y2) ? ((y1 < y3) ? y1 : y3) : ((y2 < y3) ? y2 : y3);
00539 
00549   if (end_angle < 0) {
00550     start_angle = (start_angle + end_angle + 360) % 360;
00551     end_angle = -end_angle;
00552   }
00553   angle = ((int) (start_angle / 90)) * 90;
00554   for(i = 0; i < 4; i++) {
00555     angle = angle + 90;
00556     if(angle < start_angle + end_angle) {
00557       if(angle % 360 == 0)   *right  = x1 + radius;
00558       if(angle % 360 == 90)  *bottom = y1 + radius;
00559       if(angle % 360 == 180) *left   = x1 - radius;
00560       if(angle % 360 == 270) *top    = y1 - radius;
00561     } else {
00562       break;
00563     }
00564   }
00565 
00566   /* This isn't strictly correct, but a 1st order approximation */
00567   *left   -= halfwidth;
00568   *top    -= halfwidth;
00569   *right  += halfwidth;
00570   *bottom += halfwidth;
00571 
00572 }
00573 
00584 gboolean o_arc_get_position (TOPLEVEL *toplevel, gint *x, gint *y,
00585                              OBJECT *object)
00586 {
00587   *x = object->arc->x;
00588   *y = object->arc->y;
00589   return TRUE;
00590 }
00591 
00607 void o_arc_print(TOPLEVEL *toplevel, FILE *fp, OBJECT *o_current,
00608          int origin_x, int origin_y)
00609 {
00610   int x, y, radius, start_angle, end_angle;
00611   int color;
00612   int arc_width, space, length;
00613   void (*outl_func)() = NULL;
00614 
00615   if (o_current == NULL) {
00616     printf("got null in o_arc_print\n");
00617     return;
00618   }
00619     
00620   x      = o_current->arc->x;
00621   y      = o_current->arc->y;
00622   radius = o_current->arc->width / 2;
00623   start_angle = o_current->arc->start_angle;
00624   end_angle   = o_current->arc->end_angle;
00625   color  = o_current->color;
00626 
00639 #if 0  /* was causing arcs which are solid to be much thinner compared to */
00640   /* lines, boxes, also of zero width */
00641   if (o_current->line_width > 0) {
00642     arc_width = o_current->line_width;
00643   } else {
00644     arc_width = 1;
00645   }
00646 #endif
00647   arc_width = o_current->line_width;    /* Added instead of above */
00648   if(arc_width <=2) {
00649     if(toplevel->line_style == THICK) {
00650       arc_width=LINE_WIDTH;
00651     } else {
00652       arc_width=2;
00653     }
00654   }
00655 
00656   length = o_current->line_length;
00657   space  = o_current->line_space;
00658     
00659   switch(o_current->line_type) {
00660     case(TYPE_SOLID):
00661       length = -1; space = -1;
00662       outl_func = o_arc_print_solid;
00663       break;
00664             
00665     case(TYPE_DOTTED):
00666       length = -1;
00667       outl_func = o_arc_print_dotted;
00668       break;
00669             
00670     case(TYPE_DASHED):
00671       outl_func = o_arc_print_dashed;
00672       break;
00673             
00674     case(TYPE_CENTER):
00675       outl_func = o_arc_print_center;
00676       break;
00677             
00678     case(TYPE_PHANTOM):
00679       outl_func = o_arc_print_phantom;
00680       break;
00681             
00682     case(TYPE_ERASE):
00683       /* Unused for now, print it solid */
00684       length = -1; space = -1;
00685       outl_func = o_arc_print_solid;
00686       break;
00687   }
00688 
00689   if((space == 0) || (length == 0)) {
00690     length = -1; space = -1;
00691     outl_func = o_arc_print_solid;
00692   }
00693 
00694   (*outl_func)(toplevel, fp,
00695                x - origin_x, y - origin_x, radius,
00696                start_angle, end_angle,
00697                color, arc_width, length, space, origin_x, origin_y);
00698 }
00699 
00700 
00727 void o_arc_print_solid(TOPLEVEL *toplevel, FILE *fp,
00728                int x, int y, int radius,
00729                int angle1, int angle2,
00730                int color,
00731                int arc_width, int length, int space,
00732                int origin_x, int origin_y)
00733 {
00734   f_print_set_color(toplevel, fp, color);
00735 
00736   /* inverting angle2 if < 0 and changing angle1 accordingly */
00737   if (angle2 < 0) {
00738     angle1 = angle1 + angle2;
00739     angle2 = -angle2;
00740   }
00741 
00742   fprintf(fp, "%d %d %d %d %d %d darc\n",
00743       x,y, radius, angle1, angle1 + angle2,
00744       arc_width);
00745 
00746 }
00747 
00778 void o_arc_print_dotted(TOPLEVEL *toplevel, FILE *fp,
00779             int x, int y, int radius,
00780             int angle1, int angle2,
00781             int color,                 
00782             int arc_width, int length, int space,
00783             int origin_x, int origin_y)
00784 {
00785   int da, d;
00786 
00787   f_print_set_color(toplevel, fp, color);
00788 
00801   /* Inverting angle2 if < 0 and changing angle1 accordingly */
00802   /* the loop test assume that da > 0 */
00803   if (angle2 < 0) {
00804     angle1 = angle1 + angle2;
00805     angle2 = -angle2;
00806   }
00807   da = (int) ((space * 180) / (M_PI * ((double) radius)));
00808 
00809     /* If da or db too small for arc to be displayed as dotted,
00810            draw a solid arc */
00811   if (da <= 0) {
00812     o_arc_print_solid(toplevel, fp,
00813                       x, y, radius,
00814                       angle1, angle2,
00815                       color,
00816                       arc_width, length, space, origin_x, origin_y);
00817     return;
00818   }
00819 
00820   fprintf(fp,"[");
00821   d = angle1;
00822   while (d < (angle2 + angle1)) {
00823     /*xa = ((double) x) + ((double) radius) * cos(d * M_PI / 180);
00824     ya = ((double) y) + ((double) radius) * sin(d * M_PI / 180);
00825     */
00826     fprintf(fp,"[%d] ",d);
00827 
00828     d = d + da;
00829   }
00830   fprintf(fp,"] %d %d %d %d dashedarc %% dotted\n",
00831       x,y, radius, arc_width);
00832 }
00833 
00862 void o_arc_print_dashed(TOPLEVEL *toplevel, FILE *fp,
00863             int x, int y, int radius,
00864             int angle1, int angle2,
00865             int color,                 
00866             int arc_width, int length, int space,
00867             int origin_x, int origin_y)
00868 {
00869   int da, db, a1, d;
00870 
00871   f_print_set_color(toplevel, fp, color);
00872   
00887   /* Inverting angle2 if < 0 and changing angle1 accordingly */
00888   /* the loop test assume that da > 0 */
00889   if (angle2 < 0) {
00890     angle1 = angle1 + angle2;
00891     angle2 = -angle2;
00892   }
00893   da = (int) ((length * 180) / (M_PI * ((double) radius)));
00894   db = (int) ((space  * 180) / (M_PI * ((double) radius)));
00895 
00896   /* If da or db too small for arc to be displayed as dotted,
00897            draw a solid arc */
00898   if ((da <= 0) || (db <= 0)) {
00899     o_arc_print_solid(toplevel, fp,
00900                       x, y, radius, 
00901                       angle1, angle2,
00902                       color,
00903                       arc_width, length, space, origin_x, origin_y);
00904     return;
00905   }
00906   
00907   fprintf(fp,"[");
00908   d = angle1;
00909   while ((d + da + db) < (angle1 + angle2)) {
00910     a1 = d;
00911     d = d + da;
00912 
00913     fprintf(fp,"[%d %d] ",
00914         a1, a1+da);
00915 
00916     d = d + db;
00917   }
00924   if ((d + da) < (angle1 + angle2)) {
00925     a1 = d;
00926   } else {
00927     a1 = d;
00928   }
00929 
00930   fprintf(fp,"[%d %d] ",
00931       a1, a1+da);
00932 
00933 
00934   fprintf(fp,"] %d %d %d %d dashedarc %% dashed\n",
00935       x,y, radius, arc_width);
00936 
00937 }
00938 
00967 void o_arc_print_center(TOPLEVEL *toplevel, FILE *fp,
00968             int x, int y, int radius, 
00969             int angle1, int angle2,
00970             int color,                 
00971             int arc_width, int length, int space,
00972             int origin_x, int origin_y)
00973 {
00974   int da, db, a1, d;
00975 
00976   f_print_set_color(toplevel, fp, color);
00977 
00992   /* Inverting angle2 if < 0 and changing angle1 accordingly */
00993   /* the loop test assume that da > 0 */
00994   if (angle2 < 0) {
00995     angle1 = angle1 + angle2;
00996     angle2 = -angle2;
00997   }
00998 
00999   da = (int) ((length * 180) / (M_PI * ((double) radius)));
01000   db = (int) ((space  * 180) / (M_PI * ((double) radius)));
01001 
01002   /* If da or db too small to be displayed, draw an arc */
01003   if ((da <= 0) || (db <= 0)) {
01004     o_arc_print_solid(toplevel, fp,
01005               x, y, radius,
01006               angle1, angle2,
01007               color,
01008               arc_width, length, space, origin_x, origin_y);
01009     return;
01010   }
01011   
01012   fprintf(fp, "[");
01013   d = angle1;
01014   while ((d + da + 2 * db) < (angle1 + angle2)) {
01015     a1 = d;
01016     d = d + da;
01017     fprintf(fp,"[%d %d] ",(int) a1, (int) a1 + da);
01018     
01019     d = d + db;
01020     /*
01021       xa = ((double) x) + ((double) radius) * cos(d * (M_PI / 180));
01022       ya = ((double) y) + ((double) radius) * sin(d * (M_PI / 180));
01023     */
01024     fprintf(fp,"[%d] ",d);
01025     d = d + db;
01026   }
01036   if ((d + da) < (angle1 + angle2)) {
01037     a1 = d;
01038     
01039     d = d + da;
01040   } else {
01041     a1 = d;
01042     
01043     d = d + da;
01044   }
01045   
01046   fprintf(fp,"[%d %d] ",(int) a1, (int) a1 + da);
01047 
01048     
01049   if ((d + db) < (angle1 + angle2)) {
01050     /*
01051       xa = ((double) x) + ((double) radius) * cos(d * (M_PI / 180));
01052       ya = ((double) y) + ((double) radius) * sin(d * (M_PI / 180));
01053     */
01054     fprintf(fp,"[%d] ",d);
01055     
01056   }
01057   
01058   fprintf(fp,"] %d %d %d %d dashedarc %% center\n",
01059       x,y, radius, arc_width);
01060 }
01061 
01095 void o_arc_print_phantom(TOPLEVEL *toplevel, FILE *fp,
01096              int x, int y, int radius,
01097              int angle1, int angle2,
01098              int color,
01099              int arc_width, int length, int space,
01100              int origin_x, int origin_y)
01101 {
01102   int da, db, a1, d;
01103 
01104   f_print_set_color(toplevel, fp, color);
01105 
01120   /* Inverting angle2 if < 0 and changing angle1 accordingly */
01121   /* the loop test assume that da > 0 */
01122   if (angle2 < 0) {
01123     angle1 = angle1 + angle2;
01124     angle2 = -angle2;
01125   }
01126   da = (int) ((length * 180) / (((double) radius) * M_PI));
01127   db = (int) ((space  * 180) / (((double) radius) * M_PI));
01128   
01129   /* If da or db too small for arc to be displayed as dotted,
01130      draw a solid arc */
01131   if ((da <= 0) || (db <= 0)) {
01132     o_arc_print_solid(toplevel, fp,
01133               x, y, radius,
01134               angle1, angle2,
01135               color,                          
01136               arc_width, length, space, origin_x, origin_y);
01137     return;
01138   }
01139   
01140   fprintf(fp,"[");
01141   
01142   d = angle1;
01143   while ((d + da + 3 * db) < (angle1 + angle2)) {
01144     a1 = d;
01145     d = d + da;
01146     
01147     fprintf(fp,"[%d %d] ",(int) a1, (int) a1 + da);
01148     
01149     d = d + db;
01150     /*
01151       xa = ((double) x) + ((double) radius) * cos(d * (M_PI / 180));
01152       ya = ((double) y) + ((double) radius) * sin(d * (M_PI / 180));
01153     */
01154     fprintf(fp,"[%d] ",d);
01155     
01156     d = d + db;
01157     
01158     /*
01159       xa = ((double) x) + ((double) radius) * cos(d * (M_PI / 180));
01160       ya = ((double) y) + ((double) radius) * sin(d * (M_PI / 180));
01161     */
01162     fprintf(fp,"[%d] ",d);
01163     
01164     d = d + db;
01165   }
01166 
01178   if ((d + da) < (angle1 + angle2)) {
01179     a1 = d;
01180     d = d + da;
01181   } else {
01182     a1 = d;
01183     d = d + da;
01184   }
01185   
01186   fprintf(fp,"[%d %d] ",(int) a1, (int) a1 + da);
01187   
01188   if ((d + db) < (angle1 + angle2)) {
01189     d = d + db;
01190     
01191     /*
01192       xa = ((double) x) + ((double) radius) * cos(d * (M_PI / 180));
01193       ya = ((double) y) + ((double) radius) * sin(d * (M_PI / 180));
01194     */
01195     fprintf(fp,"[%d] ",d);
01196     
01197   }
01198   
01199   if ((d + db) < (angle1 + angle2)) {
01200     d = d + db;
01201     
01202     /*
01203       xa = ((double) x) + ((double) radius) * cos(d * (M_PI / 180));
01204       ya = ((double) y) + ((double) radius) * sin(d * (M_PI / 180));
01205     */
01206     
01207     fprintf(fp,"[%d] ",d);
01208     
01209     
01210   }
01211   
01212   fprintf(fp,"] %d %d %d %d dashedarc %% phantom\n",
01213       x,y, radius, arc_width);
01214 }
01215 
01226 double o_arc_shortest_distance (OBJECT *object, int x, int y, int force_solid)
01227 {
01228   double shortest_distance;
01229   double radius;
01230 
01231   g_return_val_if_fail (object->arc != NULL, G_MAXDOUBLE);
01232 
01233   radius = ((double)object->arc->width) / 2.0;
01234 
01235   if (o_arc_within_sweep (object->arc, x, y)) {
01236     double distance_to_center;
01237     double dx;
01238     double dy;
01239 
01240     dx = ((double)x) - ((double)object->arc->x);
01241     dy = ((double)y) - ((double)object->arc->y);
01242 
01243     distance_to_center = sqrt ((dx * dx) + (dy * dy));
01244 
01245     shortest_distance = fabs (distance_to_center - radius);
01246 
01247   } else {
01248     double angle;
01249     double distance_to_end0;
01250     double distance_to_end1;
01251     double dx, dy;
01252 
01253     angle = G_PI * ((double)object->arc->start_angle) / 180;
01254 
01255     dx = ((double)x) - radius * cos (angle) - ((double)object->arc->x);
01256     dy = ((double)y) - radius * sin (angle) - ((double)object->arc->y);
01257 
01258     distance_to_end0 = sqrt ((dx * dx) + (dy * dy));
01259 
01260     angle += G_PI * ((double)object->arc->end_angle) / 180;
01261 
01262     dx = ((double)x) - radius * cos (angle) - ((double)object->arc->x);
01263     dy = ((double)y) - radius * sin (angle) - ((double)object->arc->y);
01264 
01265     distance_to_end1 = sqrt ((dx * dx) + (dy * dy));
01266 
01267     shortest_distance = min (distance_to_end0, distance_to_end1);
01268   }
01269 
01270   return shortest_distance;
01271 }
01272 
01282 gboolean o_arc_within_sweep(ARC *arc, gint x, gint y)
01283 {
01284   gdouble a0;
01285   gdouble a1;
01286   gdouble angle;
01287   gdouble dx;
01288   gdouble dy;
01289 
01290   if (arc == NULL) {
01291     g_critical("o_arc_within_sweep(): arc == NULL\n");
01292     return FALSE;
01293   }
01294 
01295   dx = ((gdouble) x) - ((gdouble) arc->x);
01296   dy = ((gdouble) y) - ((gdouble) arc->y);
01297 
01298   angle = 180 * atan2(dy, dx) / G_PI;
01299 
01300   if (arc->end_angle > 0) {
01301     a0 = arc->start_angle;
01302     a1 = arc->start_angle + arc->end_angle;
01303   } else {
01304     a0 = arc->start_angle + arc->end_angle + 360;
01305     a1 = arc->start_angle + 360;
01306   }
01307 
01308   while (angle < a0) {
01309     angle+=360;
01310   }
01311 
01312   return (angle < a1);
01313 }
01314 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines