aboutsummaryrefslogtreecommitdiff
path: root/generic
diff options
context:
space:
mode:
Diffstat (limited to 'generic')
-rw-r--r--generic/Geo.c213
-rw-r--r--generic/Geo.h9
2 files changed, 222 insertions, 0 deletions
diff --git a/generic/Geo.c b/generic/Geo.c
index 91e36a1..c07d2f5 100644
--- a/generic/Geo.c
+++ b/generic/Geo.c
@@ -2013,6 +2013,219 @@ GetBezierPath(ZnList from_points,
}
}
+
+/*
+ **********************************************************************************
+ *
+ * GetCirclePoints --
+ * Return a pointer to an array of points describing a
+ * circle arc of radius 1.0. The arc is described by start_angle,
+ * end_angle and the type: 0 for arc, 1 for chord, 2 for pie slice,
+ * 3 for a full circle (in which case start_angle and end_angle are
+ * not used.
+ * The number of points is returned in num_points. If type is not 3,
+ * point_list must not be NULL. If not NULL, it is filled with the
+ * computed points.
+ *
+ **********************************************************************************
+ */
+ZnPoint *
+GetCirclePoints(int type,
+ int quality,
+ ZnReal start_angle,
+ ZnReal end_angle,
+ int *num_points,
+ ZnList point_list)
+{
+ static ZnPoint genarc64[] = {
+ {1.0, 0.0},
+ {0.99518472653, 0.0980171417729},
+ {0.980785279837, 0.195090324861},
+ {0.956940334469, 0.290284681418},
+ {0.923879530291, 0.382683437725},
+ {0.88192126093, 0.471396743221},
+ {0.831469607468, 0.555570240255},
+ {0.773010446922, 0.634393292011},
+ {0.707106772982, 0.707106789391},
+ {0.634393274074, 0.773010461643},
+ {0.555570220961, 0.83146962036},
+ {0.471396722756, 0.881921271869},
+ {0.382683416286, 0.923879539171},
+ {0.290284659212, 0.956940341205},
+ {0.195090302102, 0.980785284364},
+ {0.0980171186795, 0.995184728805},
+ {-2.32051033331e-08, 1.0},
+ {-0.0980171648663, 0.995184724256},
+ {-0.19509034762, 0.98078527531},
+ {-0.290284703624, 0.956940327733},
+ {-0.382683459163, 0.923879521411},
+ {-0.471396763686, 0.881921249991},
+ {-0.555570259549, 0.831469594576},
+ {-0.634393309949, 0.773010432201},
+ {-0.707106805799, 0.707106756574},
+ {-0.773010476365, 0.634393256136},
+ {-0.831469633252, 0.555570201666},
+ {-0.881921282808, 0.471396702291},
+ {-0.923879548052, 0.382683394847},
+ {-0.956940347941, 0.290284637006},
+ {-0.980785288892, 0.195090279343},
+ {-0.995184731079, 0.0980170955862},
+ {-1.0, -4.64102066663e-08},
+ {-0.995184721981, -0.0980171879596},
+ {-0.980785270783, -0.195090370379},
+ {-0.956940320997, -0.29028472583},
+ {-0.923879512531, -0.382683480602},
+ {-0.881921239052, -0.471396784151},
+ {-0.831469581684, -0.555570278844},
+ {-0.77301041748, -0.634393327887},
+ {-0.707106740165, -0.707106822208},
+ {-0.634393238198, -0.773010491086},
+ {-0.555570182372, -0.831469646144},
+ {-0.471396681826, -0.881921293746},
+ {-0.382683373409, -0.923879556932},
+ {-0.2902846148, -0.956940354677},
+ {-0.195090256583, -0.980785293419},
+ {-0.0980170724928, -0.995184733354},
+ {6.96153097774e-08, -1.0},
+ {0.098017211053, -0.995184719707},
+ {0.195090393139, -0.980785266256},
+ {0.290284748036, -0.956940314261},
+ {0.382683502041, -0.923879503651},
+ {0.471396804617, -0.881921228114},
+ {0.555570298138, -0.831469568792},
+ {0.634393345825, -0.773010402759},
+ {0.707106838616, -0.707106723757},
+ {0.773010505807, -0.63439322026},
+ {0.831469659036, -0.555570163078},
+ {0.881921304685, -0.471396661361},
+ {0.923879565812, -0.38268335197},
+ {0.956940361414, -0.290284592594},
+ {0.980785297946, -0.195090233824},
+ {0.995184735628, -0.0980170493994},
+ {1.0, 0.0}};
+
+ static ZnPoint genarc20[] = {
+ {1.0, 0.0},
+ {0.951056514861, 0.309016998789},
+ {0.809016988919, 0.587785259802},
+ {0.587785241028, 0.809017002559},
+ {0.309016976719, 0.951056522032},
+ {-2.32051033331e-08, 1.0},
+ {-0.309017020858, 0.95105650769},
+ {-0.587785278575, 0.809016975279},
+ {-0.809017016198, 0.587785222255},
+ {-0.951056529203, 0.30901695465},
+ {-1.0, -4.64102066663e-08},
+ {-0.951056500519, -0.309017042928},
+ {-0.80901696164, -0.587785297348},
+ {-0.587785203482, -0.809017029838},
+ {-0.309016932581, -0.951056536373},
+ {6.96153097774e-08, -1.0},
+ {0.309017064997, -0.951056493349},
+ {0.587785316122, -0.809016948},
+ {0.809017043478, -0.587785184709},
+ {0.951056543544, -0.309016910511},
+ {1.0, 0.0}};
+
+ static ZnPoint genarc8[] = {
+ {1.0, 0.0},
+ {0.707106772982, 0.707106789391},
+ {-2.32051033331e-08, 1.0},
+ {-0.707106805799, 0.707106756574},
+ {-1.0, -4.64102066663e-08},
+ {-0.707106740165, -0.707106822208},
+ {6.96153097774e-08, -1.0},
+ {0.707106838616, -0.707106723757},
+ {1.0, 0.0}};
+ int num_p, i;
+ ZnPoint *p, *p_from;
+ ZnPoint center_p = { 0.0, 0.0 };
+ ZnPoint start_p, wp;
+ ZnReal iangle;
+
+ switch (quality) {
+ case ZN_CIRCLE_COARSE:
+ num_p = sizeof(genarc8)/sizeof(ZnPoint);
+ p = p_from = genarc8;
+ break;
+ case ZN_CIRCLE_MEDIUM:
+ num_p = sizeof(genarc20)/sizeof(ZnPoint);
+ p = p_from = genarc20;
+ break;
+ default:
+ case ZN_CIRCLE_FINEST:
+ num_p = sizeof(genarc64)/sizeof(ZnPoint);
+ p = p_from = genarc64;
+ }
+
+ if (type != 3) {
+ /*
+ * normalize start_angle and end_angle.
+ */
+ start_angle = fmod(start_angle, 2.0*M_PI);
+ if (start_angle < 0.0) {
+ start_angle += 2.0*M_PI;
+ }
+ end_angle = fmod(end_angle, 2.0*M_PI);
+ if (end_angle < 0.0) {
+ end_angle += 2.0*M_PI;
+ }
+ if (start_angle >= end_angle) {
+ if (start_angle == end_angle) {
+ type = 3;
+ }
+ end_angle += 2.0*M_PI;
+ }
+ }
+
+ /*
+ * Now 0 <= start_angle < 2 * M_PI and start_angle <= end_angle.
+ */
+ if ((type != 3) || (point_list != NULL)) {
+ if (type == 3) {
+ ZnListAssertSize(point_list, num_p);
+ p = ZnListArray(point_list);
+ for (i = 0; i < num_p; i++, p++, p_from++) {
+ *p = *p_from;
+ }
+ }
+ else {
+ ZnListEmpty(point_list);
+ iangle = 2*M_PI / (num_p-1);
+ start_p.x = cos(start_angle);
+ start_p.y = sin(start_angle);
+ ZnListAdd(point_list, &start_p, ZnListTail);
+ i = start_angle / iangle;
+ if ((i * iangle) < start_angle) {
+ i++;
+ }
+ p = &p_from[i];
+ while (start_angle < end_angle) {
+ ZnListAdd(point_list, &p[i], ZnListTail);
+ start_angle += iangle;
+ i++;
+ if (i == num_p-1) {
+ i = 0;
+ }
+ }
+ wp.x = cos(end_angle);
+ wp.y = sin(end_angle);
+ if (type == 1) {
+ ZnListAdd(point_list, &start_p, ZnListTail);
+ }
+ else if (type == 2) {
+ ZnListAdd(point_list, &center_p, ZnListTail);
+ ZnListAdd(point_list, &start_p, ZnListTail);
+ }
+ }
+ p = ZnListArray(point_list);
+ num_p = ZnListSize(point_list);
+ }
+
+ *num_points = num_p;
+ return p;
+}
+
/*
**********************************************************************************
*
diff --git a/generic/Geo.h b/generic/Geo.h
index 1304adf..5229012 100644
--- a/generic/Geo.h
+++ b/generic/Geo.h
@@ -279,6 +279,15 @@ void
GetBezierPath(ZnList from_points,
ZnList to_points);
+
+ZnPoint *
+GetCirclePoints(int type,
+ int quality,
+ ZnReal start_angle,
+ ZnReal end_angle,
+ int *num_points,
+ ZnList point_list);
+
void
GetArcPath(ZnReal start_angle,
ZnReal end_angle,