From: <hez...@us...> - 2009-08-02 05:29:29
|
Revision: 10197 http://plplot.svn.sourceforge.net/plplot/?rev=10197&view=rev Author: hezekiahcarty Date: 2009-08-02 05:29:20 +0000 (Sun, 02 Aug 2009) Log Message: ----------- Add plarc to core, along with OCaml bindings. Example 3 (C and OCaml) has also been updated to use plarc to draw polar grid circles. Modified Paths: -------------- trunk/bindings/ocaml/plplot_h trunk/bindings/ocaml/plplot_h.inc trunk/drivers/cairo.c trunk/examples/c/x03c.c trunk/examples/ocaml/x03.ml trunk/include/plplot.h trunk/include/plplotP.h trunk/include/plstrm.h trunk/src/CMakeLists.txt Added Paths: ----------- trunk/src/plarc.c Modified: trunk/bindings/ocaml/plplot_h =================================================================== --- trunk/bindings/ocaml/plplot_h 2009-07-31 18:17:38 UTC (rev 10196) +++ trunk/bindings/ocaml/plplot_h 2009-08-02 05:29:20 UTC (rev 10197) @@ -55,6 +55,10 @@ c_plcalc_world(PLFLT rx, PLFLT ry, PLFLT *wx, PLFLT *wy, PLINT *window); void +c_plarc(PLFLT x, PLFLT y, PLFLT a, PLFLT b, PLFLT angle1, PLFLT angle2, + PLBOOL fill); + + void c_plclear(void); void Modified: trunk/bindings/ocaml/plplot_h.inc =================================================================== --- trunk/bindings/ocaml/plplot_h.inc 2009-07-31 18:17:38 UTC (rev 10196) +++ trunk/bindings/ocaml/plplot_h.inc 2009-08-02 05:29:20 UTC (rev 10197) @@ -8,6 +8,7 @@ [mlname(plbox)] void c_plbox ( [string] const char * xopt, double xtick, int nxsub, [string] const char * yopt, double ytick, int nysub ); [mlname(plbox3)] void c_plbox3 ( [string] const char * xopt, [string] const char * xlabel, double xtick, int nsubx, [string] const char * yopt, [string] const char * ylabel, double ytick, int nsuby, [string] const char * zopt, [string] const char * zlabel, double ztick, int nsubz ); [mlname(plcalc_world)] void c_plcalc_world ( double rx, double ry, [out] double * wx, [out] double * wy, [out] int * window ); +[mlname(plarc)] void c_plarc ( double x, double y, double a, double b, double angle1, double angle2, boolean fill ); [mlname(plclear)] void c_plclear ( void ); [mlname(plcol0)] void c_plcol0 ( int icol0 ); [mlname(plcol1)] void c_plcol1 ( double col1 ); Modified: trunk/drivers/cairo.c =================================================================== --- trunk/drivers/cairo.c 2009-07-31 18:17:38 UTC (rev 10196) +++ trunk/drivers/cairo.c 2009-08-02 05:29:20 UTC (rev 10197) @@ -215,6 +215,7 @@ static void set_current_context(PLStream *); static void poly_line(PLStream *, short *, short *, PLINT); static void filled_polygon(PLStream *pls, short *xa, short *ya, PLINT npts); +static void arc(PLStream *, arc_struct *); static void rotate_cairo_surface(PLStream *, float, float, float, float, float, float); /* Rasterization of plotted material */ static void start_raster(PLStream*); @@ -487,6 +488,9 @@ case PLESC_END_RASTERIZE: /* End offscreen/rasterized rendering */ end_raster(pls); break; + case PLESC_ARC: /* Draw an arc, either filled or outline */ + arc(pls, (arc_struct *) ptr); + break; } } @@ -1016,6 +1020,7 @@ pls->alt_unicode = 1; /* Wants to handle unicode character by character */ pls->page = 0; pls->dev_fill0 = 1; /* Supports hardware solid fills */ + pls->dev_arc = 1; /* Supports driver-level arcs */ pls->plbuf_write = 1; /* Activate plot buffer */ @@ -1173,6 +1178,60 @@ } /*--------------------------------------------------------------------- + arc() + + Draws an arc, possibly filled. + ---------------------------------------------------------------------*/ + +void arc(PLStream *pls, arc_struct *arc_info) +{ + PLCairo *aStream; + double x, y, a, b; + double angle1, angle2; + + set_current_context(pls); + + aStream = (PLCairo *)pls->dev; + + /* Scale to the proper Cairo coordinates */ + x = aStream->downscale * arc_info->x; + y = aStream->downscale * arc_info->y; + a = aStream->downscale * arc_info->a; + b = aStream->downscale * arc_info->b; + + /* Degrees to radians */ + angle1 = arc_info->angle1 * M_PI / 180.0; + angle2 = arc_info->angle2 * M_PI / 180.0; + + cairo_save(aStream->cairoContext); + + /* Clip the output to the plotting window */ + set_clip(pls); + + /* Make sure the arc is properly shaped and oriented */ + cairo_save(aStream->cairoContext); + cairo_translate(aStream->cairoContext, x, y); + cairo_scale(aStream->cairoContext, a, b); + cairo_arc(aStream->cairoContext, 0.0, 0.0, 1.0, angle1, angle2); + if (arc_info->fill) + cairo_line_to(aStream->cairoContext, 0.0, 0.0); + cairo_restore(aStream->cairoContext); + + cairo_set_source_rgba(aStream->cairoContext, + (double)pls->curcolor.r/255.0, + (double)pls->curcolor.g/255.0, + (double)pls->curcolor.b/255.0, + (double)pls->curcolor.a); + if (arc_info->fill) { + cairo_fill(aStream->cairoContext); + } + else { + cairo_stroke(aStream->cairoContext); + } + cairo_restore(aStream->cairoContext); +} + +/*--------------------------------------------------------------------- rotate_cairo_surface() Rotates the cairo surface to the appropriate orientation. Modified: trunk/examples/c/x03c.c =================================================================== --- trunk/examples/c/x03c.c 2009-07-31 18:17:38 UTC (rev 10196) +++ trunk/examples/c/x03c.c 2009-08-02 05:29:20 UTC (rev 10197) @@ -41,15 +41,9 @@ /* Set up viewport and window, but do not draw box */ plenv(-1.3, 1.3, -1.3, 1.3, 1, -2); - for (i = 1; i <= 10; i++) { - for (j = 0; j <= 360; j++) { - x[j] = 0.1 * i * x0[j]; - y[j] = 0.1 * i * y0[j]; - } - /* Draw circles for polar grid */ - - plline(361, x, y); + for (i = 1; i <= 10; i++) { + plarc(0.0, 0.0, 0.1 * i, 0.1 * i, 0.0, 360.0, 0); } plcol0(2); Modified: trunk/examples/ocaml/x03.ml =================================================================== --- trunk/examples/ocaml/x03.ml 2009-07-31 18:17:38 UTC (rev 10196) +++ trunk/examples/ocaml/x03.ml 2009-08-02 05:29:20 UTC (rev 10197) @@ -1,7 +1,7 @@ (* $Id$ Polar plot demo. - Copyright (C) 2008 Hezekiah M. Carty + Copyright (C) 2008, 2009 Hezekiah M. Carty This file is part of PLplot. @@ -48,10 +48,9 @@ (* Set up viewport and window, but do not draw box *) plenv (-1.3) 1.3 (-1.3) 1.3 1 (-2); for i = 1 to 10 do - let x = Array.init 361 (fun j -> 0.1 *. float_of_int i *. x0.(j)) in - let y = Array.init 361 (fun j -> 0.1 *. float_of_int i *. y0.(j)) in (* Draw circles for polar grid *) - plline x y; + let r = 0.1 *. float_of_int i in + plarc 0.0 0.0 r r 0.0 360.0 false; done; plcol0 2; Modified: trunk/include/plplot.h =================================================================== --- trunk/include/plplot.h 2009-07-31 18:17:38 UTC (rev 10196) +++ trunk/include/plplot.h 2009-08-02 05:29:20 UTC (rev 10197) @@ -235,6 +235,7 @@ #define PLESC_END_TEXT 31 /* finish a drawing a line of text */ #define PLESC_START_RASTERIZE 32 /* start rasterized rendering */ #define PLESC_END_RASTERIZE 33 /* end rasterized rendering */ +#define PLESC_ARC 34 /* render an arc */ /* Alternative unicode text handling control characters */ #define PLTEXT_FONTCHANGE 0 /* font change in the text stream */ @@ -518,6 +519,7 @@ #define plbox c_plbox #define plbox3 c_plbox3 #define plcalc_world c_plcalc_world +#define plarc c_plarc #define plclear c_plclear #define plcol0 c_plcol0 #define plcol1 c_plcol1 @@ -771,6 +773,12 @@ PLDLLIMPEXP void c_plcalc_world(PLFLT rx, PLFLT ry, PLFLT *wx, PLFLT *wy, PLINT *window); +/* Plot an arc */ + +PLDLLIMPEXP void +c_plarc(PLFLT x, PLFLT y, PLFLT a, PLFLT b, PLFLT angle1, PLFLT angle2, + PLBOOL fill); + /* Clear current subpage. */ PLDLLIMPEXP void Modified: trunk/include/plplotP.h =================================================================== --- trunk/include/plplotP.h 2009-07-31 18:17:38 UTC (rev 10196) +++ trunk/include/plplotP.h 2009-08-02 05:29:20 UTC (rev 10197) @@ -932,6 +932,17 @@ plP_image(PLFLT *z, PLINT nx, PLINT ny, PLFLT xmin, PLFLT ymin, PLFLT dx, PLFLT dy, void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer), PLPointer pltr_data); +/* Structure for holding arc data */ +typedef struct { + PLFLT x; + PLFLT y; + PLFLT a; + PLFLT b; + PLFLT angle1; + PLFLT angle2; + PLBOOL fill; +} arc_struct; + /* End of page */ PLDLLIMPEXP void Modified: trunk/include/plstrm.h =================================================================== --- trunk/include/plstrm.h 2009-07-31 18:17:38 UTC (rev 10196) +++ trunk/include/plstrm.h 2009-08-02 05:29:20 UTC (rev 10197) @@ -531,7 +531,7 @@ PLINT color, colorset; PLINT family, member, finc, fflen, bytemax, famadv; PLINT dev_fill0, dev_fill1, dev_dash, dev_di, dev_flush, dev_swin; - PLINT dev_text, dev_xor, dev_clear, dev_fastimg; + PLINT dev_text, dev_xor, dev_clear, dev_fastimg, dev_arc; char DevName[80]; FILE *OutFile; Modified: trunk/src/CMakeLists.txt =================================================================== --- trunk/src/CMakeLists.txt 2009-07-31 18:17:38 UTC (rev 10196) +++ trunk/src/CMakeLists.txt 2009-08-02 05:29:20 UTC (rev 10197) @@ -21,6 +21,7 @@ set(plplot${LIB_TAG}_LIB_SRCS pdfutils.c + plarc.c plargs.c plbox.c plcont.c Added: trunk/src/plarc.c =================================================================== --- trunk/src/plarc.c (rev 0) +++ trunk/src/plarc.c 2009-08-02 05:29:20 UTC (rev 10197) @@ -0,0 +1,138 @@ +/* plarc() + * + * Copyright (C) 2009 Hezekiah M. Carty + * + * This file is part of PLplot. + * + * PLplot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Library Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * PLplot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with PLplot; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "plplotP.h" + +#define CIRCLE_SEGMENTS PL_MAXPOLY +#define DEG_TO_RAD(x) ((x) * M_PI / 180.0) + +#define PLARC_POINT_X(x, a, b, theta) ((x) + ((a) * cos(theta))) +#define PLARC_POINT_Y(y, a, b, theta) ((y) + ((b) * sin(theta))) + +/*------------------------------------------------------------------------- + * plarc_approx : Plot an approximated arc with a series of lines + * + * Takes the same arguments, with the same units, as c_plarc below. + * + *-------------------------------------------------------------------------*/ +void +plarc_approx(PLFLT x, PLFLT y, PLFLT a, PLFLT b, PLFLT angle1, PLFLT angle2, PLBOOL fill) +{ + PLINT i; + PLFLT theta0, theta_step, theta, d_angle; + PLINT segments; + PLFLT xs[CIRCLE_SEGMENTS], ys[CIRCLE_SEGMENTS]; + + /* The difference between the start and end angles */ + d_angle = DEG_TO_RAD(angle2 - angle1); + if (fabs(d_angle) > M_PI * 2.0) + d_angle = M_PI * 2.0; + + /* The number of line segments used to approximate the arc */ + segments = d_angle / (2.0 * M_PI) * CIRCLE_SEGMENTS; + /* Always use at least 2 arc points, otherwise fills will break. */ + if (segments < 2) + segments = 2; + /* The start angle in radians and number of radians in each approximating + segment. */ + theta0 = DEG_TO_RAD(angle1); + + theta_step = d_angle / (segments - 1); + + /* The coordinates for the circle outline */ + for (i = 0; i < segments; i++) { + theta = theta0 + theta_step * (PLFLT) i; + xs[i] = PLARC_POINT_X(x, a, b, theta); + ys[i] = PLARC_POINT_Y(y, a, b, theta); + } + + if (fill) { + /* Add the center point if we aren't drawing a circle */ + if (fabs(d_angle) < M_PI * 2.0) { + xs[segments - 1] = x; + ys[segments - 1] = y; + } + /* Draw a filled arc */ + plfill(segments, xs, ys); + } + else { + /* Draw the arc outline */ + plline(segments, xs, ys); + } +} + +/*------------------------------------------------------------------------- + * plarc : Plot an arc + * + * Takes the following arguments: + * + * x, y: + * x and y coordinates for the center of the arc + * + * a, b: + * Radius of the arc's major and minor axes + * + * angle1: + * Start angle (degrees) + * + * angle2: + * End angle (degrees) + * + * fill: + * Should the arc be filled? + * + *-------------------------------------------------------------------------*/ +void +c_plarc(PLFLT x, PLFLT y, PLFLT a, PLFLT b, PLFLT angle1, PLFLT angle2, PLBOOL fill) +{ + PLINT xscl[2], yscl[2]; + PLINT clpxmi, clpxma, clpymi, clpyma; + PLFLT orientation_offset, orientation; + arc_struct *arc_info; + + /* TODO: For now, only unrotated plots use the driver-accelerated path. */ + if (plsc->dev_arc && plsc->diorot == 0) { + arc_info = (arc_struct *) malloc((size_t) sizeof(arc_struct)); + + xscl[0] = plP_wcpcx(x-a); + xscl[1] = plP_wcpcx(x+a); + yscl[0] = plP_wcpcy(y-b); + yscl[1] = plP_wcpcy(y+b); + difilt(xscl,yscl,2,&clpxmi,&clpxma,&clpymi,&clpyma); + + arc_info->x = 0.5 * (xscl[1] + xscl[0]); + arc_info->y = 0.5 * (yscl[1] + yscl[0]); + arc_info->a = 0.5 * (xscl[1] - xscl[0]); + arc_info->b = 0.5 * (yscl[1] - yscl[0]); + + arc_info->angle1 = angle1; + arc_info->angle2 = angle2; + arc_info->fill = fill; + + plP_esc(PLESC_ARC, arc_info); + + free(arc_info); + } + else { + plarc_approx(x, y, a, b, angle1, angle2, fill); + } +} + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |