[gimp] app: add gimp_transform_polygon()
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add gimp_transform_polygon()
- Date: Sun, 28 Jan 2018 21:38:17 +0000 (UTC)
commit cc20cb41f38f0f28241c7e41f330b418e2013ad1
Author: Ell <ell_se yahoo com>
Date: Sun Jan 28 09:41:19 2018 -0500
app: add gimp_transform_polygon()
gimp_transform_polygon() transforms an (open or closed) polygon by
a GimpMatrix3, performing clipping to the near plane, to avoid
erroneously transforming points behind the camera.
app/core/gimp-transform-utils.c | 77 +++++++++++++++++++++++++++++++++++++++
app/core/gimp-transform-utils.h | 7 ++++
2 files changed, 84 insertions(+), 0 deletions(-)
---
diff --git a/app/core/gimp-transform-utils.c b/app/core/gimp-transform-utils.c
index 3801052..a58ce94 100644
--- a/app/core/gimp-transform-utils.c
+++ b/app/core/gimp-transform-utils.c
@@ -27,6 +27,7 @@
#define EPSILON 1e-6
+#define NEAR_Z 0.02
void
@@ -506,3 +507,79 @@ gimp_transform_polygon_is_convex (gdouble x1,
return (z1 * z2 > 0) && (z3 * z4 > 0);
}
+
+void
+gimp_transform_polygon (const GimpMatrix3 *matrix,
+ const GimpVector2 *vertices,
+ gint n_vertices,
+ gboolean closed,
+ GimpVector2 *t_vertices,
+ gint *n_t_vertices)
+{
+ GimpVector3 curr;
+ gboolean curr_visible;
+ gint i;
+
+ g_return_if_fail (matrix != NULL);
+ g_return_if_fail (vertices != NULL);
+ g_return_if_fail (n_vertices >= 0);
+ g_return_if_fail (t_vertices != NULL);
+ g_return_if_fail (n_t_vertices != NULL);
+
+ *n_t_vertices = 0;
+
+ if (n_vertices == 0)
+ return;
+
+ curr.x = matrix->coeff[0][0] * vertices[0].x +
+ matrix->coeff[0][1] * vertices[0].y +
+ matrix->coeff[0][2];
+ curr.y = matrix->coeff[1][0] * vertices[0].x +
+ matrix->coeff[1][1] * vertices[0].y +
+ matrix->coeff[1][2];
+ curr.z = matrix->coeff[2][0] * vertices[0].x +
+ matrix->coeff[2][1] * vertices[0].y +
+ matrix->coeff[2][2];
+
+ curr_visible = (curr.z >= NEAR_Z);
+
+ for (i = 0; i < n_vertices; i++)
+ {
+ if (curr_visible)
+ {
+ t_vertices[(*n_t_vertices)++] = (GimpVector2) { curr.x / curr.z,
+ curr.y / curr.z };
+ }
+
+ if (i < n_vertices - 1 || closed)
+ {
+ GimpVector3 next;
+ gboolean next_visible;
+ gint j = (i + 1) % n_vertices;
+
+ next.x = matrix->coeff[0][0] * vertices[j].x +
+ matrix->coeff[0][1] * vertices[j].y +
+ matrix->coeff[0][2];
+ next.y = matrix->coeff[1][0] * vertices[j].x +
+ matrix->coeff[1][1] * vertices[j].y +
+ matrix->coeff[1][2];
+ next.z = matrix->coeff[2][0] * vertices[j].x +
+ matrix->coeff[2][1] * vertices[j].y +
+ matrix->coeff[2][2];
+
+ next_visible = (next.z >= NEAR_Z);
+
+ if (next_visible != curr_visible)
+ {
+ gdouble ratio = (curr.z - NEAR_Z) / (curr.z - next.z);
+
+ t_vertices[(*n_t_vertices)++] =
+ (GimpVector2) { (curr.x + (next.x - curr.x) * ratio) / NEAR_Z,
+ (curr.y + (next.y - curr.y) * ratio) / NEAR_Z };
+ }
+
+ curr = next;
+ curr_visible = next_visible;
+ }
+ }
+}
diff --git a/app/core/gimp-transform-utils.h b/app/core/gimp-transform-utils.h
index 4233f4e..2c4c08f 100644
--- a/app/core/gimp-transform-utils.h
+++ b/app/core/gimp-transform-utils.h
@@ -98,5 +98,12 @@ gboolean gimp_transform_polygon_is_convex (gdouble x1,
gdouble x4,
gdouble y4);
+void gimp_transform_polygon (const GimpMatrix3 *matrix,
+ const GimpVector2 *vertices,
+ gint n_vertices,
+ gboolean closed,
+ GimpVector2 *t_vertices,
+ gint *n_t_vertices);
+
#endif /* __GIMP_TRANSFORM_UTILS_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]