aboutsummaryrefslogtreecommitdiff
path: root/generic/Geo.c
diff options
context:
space:
mode:
authorlecoanet2004-01-26 09:35:10 +0000
committerlecoanet2004-01-26 09:35:10 +0000
commit8b517a26a21a3abb8c8d7d2c0412ea207b633721 (patch)
treea6091c39b34fecfe8acaf4876e0030ac35c04b13 /generic/Geo.c
parent217fd7bdd06f4e0f3a607098044a9df39ad375ad (diff)
downloadtkzinc-8b517a26a21a3abb8c8d7d2c0412ea207b633721.zip
tkzinc-8b517a26a21a3abb8c8d7d2c0412ea207b633721.tar.gz
tkzinc-8b517a26a21a3abb8c8d7d2c0412ea207b633721.tar.bz2
tkzinc-8b517a26a21a3abb8c8d7d2c0412ea207b633721.tar.xz
ZnLineToPointDist can optionally return the closest point on the line.
Added ZnRectOrigin2Anchor to compute the anchor position on any rectangles (ZnOrigin2Anchor works only for bounding boxes).
Diffstat (limited to 'generic/Geo.c')
-rw-r--r--generic/Geo.c70
1 files changed, 63 insertions, 7 deletions
diff --git a/generic/Geo.c b/generic/Geo.c
index b1ad802..5a284c1 100644
--- a/generic/Geo.c
+++ b/generic/Geo.c
@@ -227,6 +227,56 @@ ZnOrigin2Anchor(ZnPoint *origin,
}
}
+/*
+ * Compute the anchor position given a rectangle and
+ * the anchor. The rectangle vertices must be ordered
+ * as for a triangle strip:
+ *
+ * v0 ------------ v2
+ * | |
+ * | |
+ * v1 ------------ v3
+ */
+void
+ZnRectOrigin2Anchor(ZnPoint *rect,
+ Tk_Anchor anchor,
+ ZnPoint *position)
+{
+ switch (anchor) {
+ case TK_ANCHOR_CENTER:
+ position->x = (rect[0].x + rect[3].x) / 2.0;
+ position->y = (rect[0].y + rect[3].y) / 2.0;
+ break;
+ case TK_ANCHOR_NW:
+ *position = *rect;
+ break;
+ case TK_ANCHOR_N:
+ position->x = (rect[0].x + rect[2].x) / 2.0;
+ position->y = (rect[0].y + rect[2].y) / 2.0;
+ break;
+ case TK_ANCHOR_NE:
+ *position = rect[2];
+ break;
+ case TK_ANCHOR_E:
+ position->x = (rect[2].x + rect[3].x) / 2.0;
+ position->y = (rect[2].y + rect[3].y) / 2.0;
+ break;
+ case TK_ANCHOR_SE:
+ *position = rect[3];
+ break;
+ case TK_ANCHOR_S:
+ position->x = (rect[1].x + rect[3].x) / 2.0;
+ position->y = (rect[1].y + rect[3].y) / 2.0;
+ break;
+ case TK_ANCHOR_SW:
+ *position = rect[1];
+ break;
+ case TK_ANCHOR_W:
+ position->x = (rect[0].x + rect[1].x) / 2.0;
+ position->y = (rect[0].y + rect[1].y) / 2.0;
+ break;
+ }
+}
void
ZnBBox2XRect(ZnBBox *bbox,
@@ -1392,14 +1442,14 @@ ZnRectangleToPointDist(ZnBBox *bbox,
p1.x = bbox->orig.x;
p1.y = p2.y = bbox->orig.y;
p2.x = bbox->corner.x;
- dist = ZnLineToPointDist(&p1, &p2, p);
+ dist = ZnLineToPointDist(&p1, &p2, p, NULL);
if (dist == 0.0) {
return 0.0;
}
p1 = p2;
p2.y = bbox->corner.y;
- new_dist = ZnLineToPointDist(&p1, &p2, p);
+ new_dist = ZnLineToPointDist(&p1, &p2, p, NULL);
dist = MIN(dist, new_dist);
if (dist == 0.0) {
return 0.0;
@@ -1407,7 +1457,7 @@ ZnRectangleToPointDist(ZnBBox *bbox,
p1 = p2;
p2.x = bbox->orig.x;
- new_dist = ZnLineToPointDist(&p1, &p2, p);
+ new_dist = ZnLineToPointDist(&p1, &p2, p, NULL);
dist = MIN(dist, new_dist);
if (dist == 0.0) {
return 0.0;
@@ -1415,7 +1465,7 @@ ZnRectangleToPointDist(ZnBBox *bbox,
p1 = p2;
p2.y = bbox->orig.y;
- new_dist = ZnLineToPointDist(&p1, &p2, p);
+ new_dist = ZnLineToPointDist(&p1, &p2, p, NULL);
dist = MIN(dist, new_dist);
if (ZnPointInBBox(bbox, p->x, p->y)) {
@@ -1434,7 +1484,8 @@ ZnRectangleToPointDist(ZnBBox *bbox,
ZnDim
ZnLineToPointDist(ZnPoint *p1,
ZnPoint *p2,
- ZnPoint *p)
+ ZnPoint *p,
+ ZnPoint *closest)
{
ZnReal x, y;
ZnReal x_int, y_int;
@@ -1511,6 +1562,11 @@ ZnLineToPointDist(ZnPoint *p1,
}
}
}
+
+ if (closest) {
+ closest->x = x;
+ closest->y = y;
+ }
/* Return the distance */
return hypot(p->x - x, p->y - y);
@@ -1994,9 +2050,9 @@ ZnGetBezierPoints(ZnPoint *p1,
{
ZnReal dist;
- dist = ZnLineToPointDist(p1, p2, c1);
+ dist = ZnLineToPointDist(p1, p2, c1, NULL);
if ((dist < eps) && ((c1->x != c2->x) || (c1->y != c2->y))) {
- dist = ZnLineToPointDist(p1, p2, c2);
+ dist = ZnLineToPointDist(p1, p2, c2, NULL);
}
if (dist > eps) {