PLplot 5.15.0
Loading...
Searching...
No Matches
plarc.c
Go to the documentation of this file.
1// plarc()
2//
3// Copyright (C) 2009 Hezekiah M. Carty
4//
5// This file is part of PLplot.
6//
7// PLplot is free software; you can redistribute it and/or modify
8// it under the terms of the GNU Library General Public License as published
9// by the Free Software Foundation; either version 2 of the License, or
10// (at your option) any later version.
11//
12// PLplot is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU Library General Public License for more details.
16//
17// You should have received a copy of the GNU Library General Public License
18// along with PLplot; if not, write to the Free Software
19// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20//
21
25
26#include "plplotP.h"
27
28#define CIRCLE_SEGMENTS ( PL_MAXPOLY - 1 )
29#define DEG_TO_RAD( x ) ( ( x ) * M_PI / 180.0 )
30
31void plarc_approx( PLFLT x, PLFLT y, PLFLT a, PLFLT b, PLFLT angle1, PLFLT angle2, PLFLT rotate, PLBOOL fill );
32
33//--------------------------------------------------------------------------
34// plarc_approx : Plot an approximated arc with a series of lines
35//
49//--------------------------------------------------------------------------
50void
51plarc_approx( PLFLT x, PLFLT y, PLFLT a, PLFLT b, PLFLT angle1, PLFLT angle2, PLFLT rotate, PLBOOL fill )
52{
53 PLINT i;
54 PLFLT theta0, theta_step, theta, d_angle;
55 PLINT segments;
56 PLFLT xs[CIRCLE_SEGMENTS + 1], ys[CIRCLE_SEGMENTS + 1];
57 PLFLT cphi, sphi, ctheta, stheta;
58
59 // The difference between the start and end angles
60 d_angle = DEG_TO_RAD( angle2 - angle1 );
61 if ( fabs( d_angle ) > M_PI * 2.0 )
62 d_angle = M_PI * 2.0;
63
64 // Calculate cosine and sine of angle of major axis wrt the x axis
65 cphi = cos( DEG_TO_RAD( rotate ) );
66 sphi = sin( DEG_TO_RAD( rotate ) );
67
68 // The number of line segments used to approximate the arc
69 segments = (PLINT) ( fabs( d_angle ) / ( 2.0 * M_PI ) * CIRCLE_SEGMENTS );
70 // Always use at least 2 arc points, otherwise fills will break.
71 if ( segments < 2 )
72 segments = 2;
73 // The start angle in radians and number of radians in each approximating
74 // segment.
75 theta0 = DEG_TO_RAD( angle1 );
76
77 theta_step = d_angle / ( segments - 1 );
78
79 // The coordinates for the circle outline
80 for ( i = 0; i < segments; i++ )
81 {
82 theta = theta0 + theta_step * (PLFLT) i;
83 ctheta = cos( theta );
84 stheta = sin( theta );
85 xs[i] = x + a * ctheta * cphi - b * stheta * sphi;
86 ys[i] = y + a * ctheta * sphi + b * stheta * cphi;
87 }
88
89 if ( fill )
90 {
91 // Add the center point if we aren't drawing a circle
92 if ( fabs( d_angle ) < M_PI * 2.0 )
93 {
94 xs[segments] = x;
95 ys[segments] = y;
96 segments++;
97 }
98 // Draw a filled arc
99 plfill( segments, xs, ys );
100 }
101 else
102 {
103 // Draw the arc outline
104 plline( segments, xs, ys );
105 }
106}
107
108//--------------------------------------------------------------------------
109// plarc : Plot an arc
110//
138//
139//--------------------------------------------------------------------------
140void
141c_plarc( PLFLT x, PLFLT y, PLFLT a, PLFLT b, PLFLT angle1, PLFLT angle2, PLFLT rotate, PLBOOL fill )
142{
143 PLINT xscl[2], yscl[2];
144 PLINT clpxmi, clpxma, clpymi, clpyma;
145 arc_struct *arc_info;
146
147 // TODO: For now, only unrotated plots use the driver-accelerated path.
148 if ( plsc->dev_arc && plsc->diorot == 0 )
149 {
150 arc_info = (arc_struct *) malloc( (size_t) sizeof ( arc_struct ) );
151
152 xscl[0] = plP_wcpcx( x - a );
153 xscl[1] = plP_wcpcx( x + a );
154 yscl[0] = plP_wcpcy( y - b );
155 yscl[1] = plP_wcpcy( y + b );
156 difilt( xscl, yscl, 2, &clpxmi, &clpxma, &clpymi, &clpyma );
157
158 arc_info->x = 0.5 * ( xscl[1] + xscl[0] );
159 arc_info->y = 0.5 * ( yscl[1] + yscl[0] );
160 arc_info->a = 0.5 * ( xscl[1] - xscl[0] );
161 arc_info->b = 0.5 * ( yscl[1] - yscl[0] );
162
163 arc_info->angle1 = angle1;
164 arc_info->angle2 = angle2;
165 arc_info->rotate = rotate;
166 arc_info->fill = fill;
167
168 plP_esc( PLESC_ARC, arc_info );
169
170 free( arc_info );
171 }
172 else
173 {
174 plarc_approx( x, y, a, b, angle1, angle2, rotate, fill );
175 }
176}
177
void plarc_approx(PLFLT x, PLFLT y, PLFLT a, PLFLT b, PLFLT angle1, PLFLT angle2, PLFLT rotate, PLBOOL fill)
Definition: plarc.c:51
#define DEG_TO_RAD(x)
Definition: plarc.c:29
void c_plarc(PLFLT x, PLFLT y, PLFLT a, PLFLT b, PLFLT angle1, PLFLT angle2, PLFLT rotate, PLBOOL fill)
Definition: plarc.c:141
#define CIRCLE_SEGMENTS
Definition: plarc.c:28
void difilt(PLINT *xsc, PLINT *ysc, PLINT npts, PLINT *clpxmi, PLINT *clpxma, PLINT *clpymi, PLINT *clpyma)
Definition: plcore.c:1460
void plP_esc(PLINT op, void *ptr)
Definition: plcore.c:273
static PLINT xscl[PL_MAXPOLY]
Definition: plcore.h:70
static PLINT yscl[PL_MAXPOLY]
Definition: plcore.h:70
PLINT plP_wcpcy(PLFLT y)
Definition: plcvt.c:73
PLINT plP_wcpcx(PLFLT x)
Definition: plcvt.c:63
#define M_PI
Definition: plplotP.h:119
#define plfill
Definition: plplot.h:717
float PLFLT
Definition: plplot.h:163
#define plline
Definition: plplot.h:760
#define PLESC_ARC
Definition: plplot.h:304
int PLINT
Definition: plplot.h:181
PLINT PLBOOL
Definition: plplot.h:204
PLFLT x
Definition: plplotP.h:1103
PLFLT b
Definition: plplotP.h:1106
PLFLT angle2
Definition: plplotP.h:1108
PLFLT y
Definition: plplotP.h:1104
PLFLT rotate
Definition: plplotP.h:1109
PLFLT a
Definition: plplotP.h:1105
PLFLT angle1
Definition: plplotP.h:1107
PLBOOL fill
Definition: plplotP.h:1110