PLplot
5.10.0
|
00001 // plarc() 00002 // 00003 // Copyright (C) 2009 Hezekiah M. Carty 00004 // 00005 // This file is part of PLplot. 00006 // 00007 // PLplot is free software; you can redistribute it and/or modify 00008 // it under the terms of the GNU Library General Public License as published 00009 // by the Free Software Foundation; either version 2 of the License, or 00010 // (at your option) any later version. 00011 // 00012 // PLplot is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU Library General Public License for more details. 00016 // 00017 // You should have received a copy of the GNU Library General Public License 00018 // along with PLplot; if not, write to the Free Software 00019 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 // 00021 00025 00026 #include "plplotP.h" 00027 00028 #define CIRCLE_SEGMENTS ( PL_MAXPOLY - 1 ) 00029 #define DEG_TO_RAD( x ) ( ( x ) * M_PI / 180.0 ) 00030 00031 void plarc_approx( PLFLT x, PLFLT y, PLFLT a, PLFLT b, PLFLT angle1, PLFLT angle2, PLFLT rotate, PLBOOL fill ); 00032 00033 //-------------------------------------------------------------------------- 00034 // plarc_approx : Plot an approximated arc with a series of lines 00035 // 00049 //-------------------------------------------------------------------------- 00050 void 00051 plarc_approx( PLFLT x, PLFLT y, PLFLT a, PLFLT b, PLFLT angle1, PLFLT angle2, PLFLT rotate, PLBOOL fill ) 00052 { 00053 PLINT i; 00054 PLFLT theta0, theta_step, theta, d_angle; 00055 PLINT segments; 00056 PLFLT xs[CIRCLE_SEGMENTS + 1], ys[CIRCLE_SEGMENTS + 1]; 00057 PLFLT cphi, sphi, ctheta, stheta; 00058 00059 // The difference between the start and end angles 00060 d_angle = DEG_TO_RAD( angle2 - angle1 ); 00061 if ( fabs( d_angle ) > M_PI * 2.0 ) 00062 d_angle = M_PI * 2.0; 00063 00064 // Calculate cosine and sine of angle of major axis wrt the x axis 00065 cphi = cos( DEG_TO_RAD( rotate ) ); 00066 sphi = sin( DEG_TO_RAD( rotate ) ); 00067 00068 // The number of line segments used to approximate the arc 00069 segments = (PLINT) ( fabs( d_angle ) / ( 2.0 * M_PI ) * CIRCLE_SEGMENTS ); 00070 // Always use at least 2 arc points, otherwise fills will break. 00071 if ( segments < 2 ) 00072 segments = 2; 00073 // The start angle in radians and number of radians in each approximating 00074 // segment. 00075 theta0 = DEG_TO_RAD( angle1 ); 00076 00077 theta_step = d_angle / ( segments - 1 ); 00078 00079 // The coordinates for the circle outline 00080 for ( i = 0; i < segments; i++ ) 00081 { 00082 theta = theta0 + theta_step * (PLFLT) i; 00083 ctheta = cos( theta ); 00084 stheta = sin( theta ); 00085 xs[i] = x + a * ctheta * cphi - b * stheta * sphi; 00086 ys[i] = y + a * ctheta * sphi + b * stheta * cphi; 00087 } 00088 00089 if ( fill ) 00090 { 00091 // Add the center point if we aren't drawing a circle 00092 if ( fabs( d_angle ) < M_PI * 2.0 ) 00093 { 00094 xs[segments] = x; 00095 ys[segments] = y; 00096 segments++; 00097 } 00098 // Draw a filled arc 00099 plfill( segments, xs, ys ); 00100 } 00101 else 00102 { 00103 // Draw the arc outline 00104 plline( segments, xs, ys ); 00105 } 00106 } 00107 00108 //-------------------------------------------------------------------------- 00109 // plarc : Plot an arc 00110 // 00138 // 00139 //-------------------------------------------------------------------------- 00140 void 00141 c_plarc( PLFLT x, PLFLT y, PLFLT a, PLFLT b, PLFLT angle1, PLFLT angle2, PLFLT rotate, PLBOOL fill ) 00142 { 00143 PLINT xscl[2], yscl[2]; 00144 PLINT clpxmi, clpxma, clpymi, clpyma; 00145 arc_struct *arc_info; 00146 00147 // TODO: For now, only unrotated plots use the driver-accelerated path. 00148 if ( plsc->dev_arc && plsc->diorot == 0 ) 00149 { 00150 arc_info = (arc_struct *) malloc( (size_t) sizeof ( arc_struct ) ); 00151 00152 xscl[0] = plP_wcpcx( x - a ); 00153 xscl[1] = plP_wcpcx( x + a ); 00154 yscl[0] = plP_wcpcy( y - b ); 00155 yscl[1] = plP_wcpcy( y + b ); 00156 difilt( xscl, yscl, 2, &clpxmi, &clpxma, &clpymi, &clpyma ); 00157 00158 arc_info->x = 0.5 * ( xscl[1] + xscl[0] ); 00159 arc_info->y = 0.5 * ( yscl[1] + yscl[0] ); 00160 arc_info->a = 0.5 * ( xscl[1] - xscl[0] ); 00161 arc_info->b = 0.5 * ( yscl[1] - yscl[0] ); 00162 00163 arc_info->angle1 = angle1; 00164 arc_info->angle2 = angle2; 00165 arc_info->rotate = rotate; 00166 arc_info->fill = fill; 00167 00168 plP_esc( PLESC_ARC, arc_info ); 00169 00170 free( arc_info ); 00171 } 00172 else 00173 { 00174 plarc_approx( x, y, a, b, angle1, angle2, rotate, fill ); 00175 } 00176 } 00177