[gtk/matthiasc/lottie2: 39/40] Implement gsk_circle_contour_get_closest_point
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/matthiasc/lottie2: 39/40] Implement gsk_circle_contour_get_closest_point
- Date: Thu, 26 Nov 2020 02:04:17 +0000 (UTC)
commit 307542ad22adb118300e0d3b13b5df26dc152bbf
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Nov 25 18:34:01 2020 -0500
Implement gsk_circle_contour_get_closest_point
gsk/gskpath.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 60 insertions(+), 2 deletions(-)
---
diff --git a/gsk/gskpath.c b/gsk/gskpath.c
index 788c9bd843..cccab73466 100644
--- a/gsk/gskpath.c
+++ b/gsk/gskpath.c
@@ -476,6 +476,7 @@ gsk_rect_contour_init (GskContour *contour,
/* CIRCLE CONTOUR */
#define DEG_TO_RAD(x) ((x) * (G_PI / 180.f))
+#define RAD_TO_DEG(x) ((x) / (G_PI / 180.f))
typedef struct _GskCircleContour GskCircleContour;
struct _GskCircleContour
@@ -642,8 +643,65 @@ gsk_circle_contour_get_closest_point (const GskContour *contour,
float *out_offset,
graphene_vec2_t *out_tangent)
{
- g_warning ("FIXME");
- return FALSE;
+ const GskCircleContour *self = (const GskCircleContour *) contour;
+ graphene_vec2_t dir;
+ float angle;
+ float closest_angle;
+ float offset;
+ graphene_point_t pos;
+ graphene_vec2_t tangent;
+ float distance;
+
+ if (graphene_point_distance (point, &self->center, NULL, NULL) > threshold + self->radius)
+ return FALSE;
+
+ graphene_vec2_init (&dir,
+ point->x - self->center.x,
+ point->y - self->center.y);
+ graphene_vec2_normalize (&dir, &dir);
+ angle = acos (graphene_vec2_dot (&dir, graphene_vec2_x_axis ()));
+ if (point->y - self->center.y < 0)
+ angle = 2*M_PI - angle;
+
+ angle = RAD_TO_DEG (angle);
+
+ if ((self->start_angle <= angle && angle <= self->end_angle) ||
+ (self->end_angle <= angle && angle <= self->start_angle))
+ {
+ closest_angle = angle;
+ }
+ else
+ {
+ float d1, d2;
+
+ d1 = fabs (self->start_angle - angle);
+ d1 = MIN (d1, 360 - d1);
+ d2 = fabs (self->end_angle - angle);
+ d2 = MIN (d2, 360 - d2);
+ if (d1 < d2)
+ closest_angle = self->start_angle;
+ else
+ closest_angle = self->end_angle;
+ }
+
+ offset = self->radius * 2 * M_PI * (closest_angle - self->start_angle) / (self->end_angle -
self->start_angle);
+
+ gsk_circle_contour_get_point (contour, NULL, offset, &pos, out_tangent ? &tangent : NULL);
+
+ distance = graphene_point_distance (&pos, point, NULL, NULL);
+ if (threshold < distance)
+ return FALSE;
+
+ if (out_offset)
+ *out_offset = offset;
+ if (out_pos)
+ *out_pos = pos;
+ if (out_distance)
+ *out_distance = distance;
+ if (out_tangent)
+ *out_tangent = tangent;
+
+ return TRUE;
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]