[gegl/soc-2013-opecl-ops] operations: Bug 677275 - Mosaic Filter produces ugly artifacts
- From: Carlos Zubieta <czubieta src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/soc-2013-opecl-ops] operations: Bug 677275 - Mosaic Filter produces ugly artifacts
- Date: Mon, 23 Sep 2013 20:59:47 +0000 (UTC)
commit 8519e3c2cee9b0c0ae4071a026ee708d73d6a0be
Author: Téo Mazars <teo mazars ensimag fr>
Date: Sun Sep 22 14:52:02 2013 +0200
operations: Bug 677275 - Mosaic Filter produces ugly artifacts
Use a correct segment-point distance.
operations/common/mosaic.c | 55 ++++++++++++++++++++++++++++++++++++++-----
1 files changed, 48 insertions(+), 7 deletions(-)
---
diff --git a/operations/common/mosaic.c b/operations/common/mosaic.c
index 1b039fc..48648bb 100644
--- a/operations/common/mosaic.c
+++ b/operations/common/mosaic.c
@@ -122,6 +122,7 @@ typedef struct
typedef struct
{
gdouble base_x, base_y;
+ gdouble base_x2, base_y2;
gdouble norm_x, norm_y;
gdouble light;
} SpecVec;
@@ -319,6 +320,9 @@ static gint rand_i (gint seed,
gfloat pos_y,
gint min,
gint max);
+static gfloat distance (SpecVec *vec,
+ gfloat x,
+ gfloat y);
#define ROUND(x) ((gint) ((((x) < 0) ? (x) - 0.5 : (x) + 0.5)))
@@ -2130,10 +2134,12 @@ calc_spec_vec (SpecVec *vec,
vec->base_x = x1;
vec->base_y = y1;
+ vec->base_x2 = x2;
+ vec->base_y2 = y2;
r = sqrt (SQR (x2 - x1) + SQR (y2 - y1));
- if (r > 0.0)
+ if (r > EPSILON)
{
vec->norm_x = - (y2 - y1) / r;
vec->norm_y = (x2 - x1) / r;
@@ -2147,6 +2153,45 @@ calc_spec_vec (SpecVec *vec,
vec->light = vec->norm_x * light_x + vec->norm_y * light_y;
}
+static gfloat
+distance (SpecVec *vec,
+ gfloat x,
+ gfloat y)
+{
+ gfloat l2, t;
+ gfloat pv_x, pv_y;
+ gfloat pw_x, pw_y;
+ gfloat wv_x, wv_y;
+ gfloat proj_x, proj_y;
+
+ l2 = SQR (vec->base_x - vec->base_x2) + SQR (vec->base_y - vec->base_y2);
+
+ if (l2 < EPSILON)
+ return sqrt (SQR (vec->base_x - x) + SQR (vec->base_y - y));
+
+ pv_x = x - vec->base_x;
+ pv_y = y - vec->base_y;
+
+ pw_x = x - vec->base_x2;
+ pw_y = y - vec->base_y2;
+
+ wv_x = vec->base_x2 - vec->base_x;
+ wv_y = vec->base_y2 - vec->base_y;
+
+ t = (pv_x * wv_x + pv_y * wv_y) / l2;
+
+ if (t < 0.0)
+ return sqrt (SQR (pv_x) + SQR (pv_y));
+
+ else if (t > 1.0)
+ return sqrt (SQR (pw_x) + SQR (pw_y));
+
+ proj_x = vec->base_x + t * wv_x;
+ proj_y = vec->base_y + t * wv_y;
+
+ return sqrt (SQR (x - proj_x) + SQR (y - proj_y));
+}
+
static double
calc_spec_contrib (SpecVec *vecs,
@@ -2161,13 +2206,9 @@ calc_spec_contrib (SpecVec *vecs,
for (i = 0; i < n; i++)
{
- gdouble x_p, y_p;
- gdouble dist;
-
- x_p = x - vecs[i].base_x;
- y_p = y - vecs[i].base_y;
+ gfloat dist;
- dist = fabs (x_p * vecs[i].norm_x + y_p * vecs[i].norm_y);
+ dist = distance (vecs+i, x, y);
if (tile_rough)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]