summaryrefslogtreecommitdiff
path: root/meme/slice.c
diff options
context:
space:
mode:
authorWerner Almesberger <werner@almesberger.net>2015-03-16 22:16:52 (GMT)
committerWerner Almesberger <werner@almesberger.net>2015-03-16 22:16:52 (GMT)
commitacf7975a64c6b99b44f11eddd0b778491f84c9a1 (patch)
treece18cbef0bfbc781947a252552616cb96a370ba5 /meme/slice.c
parentc8c50dc710229113e9302e45b1fead950af7dff0 (diff)
downloadmisc-acf7975a64c6b99b44f11eddd0b778491f84c9a1.zip
misc-acf7975a64c6b99b44f11eddd0b778491f84c9a1.tar.gz
misc-acf7975a64c6b99b44f11eddd0b778491f84c9a1.tar.bz2
meme/slice.c: needle model: avoid segments that consist of a single point
We could get these when jumping back to the edge point on e > d. This reduces the number of lines in the gnuplot output by about 30%.
Diffstat (limited to 'meme/slice.c')
-rw-r--r--meme/slice.c54
1 files changed, 36 insertions, 18 deletions
diff --git a/meme/slice.c b/meme/slice.c
index 3b41965..3d06521 100644
--- a/meme/slice.c
+++ b/meme/slice.c
@@ -102,7 +102,11 @@ static bool above(const struct vertex *v)
}
-static bool solve(const struct vertex *va, const struct vertex *vb, double *res)
+/* --- Interpolation --- */
+
+
+static bool inter_solve(const struct vertex *va, const struct vertex *vb,
+ double *res)
{
double dx, dy, dz;
double m, a;
@@ -134,7 +138,7 @@ static bool solve(const struct vertex *va, const struct vertex *vb, double *res)
}
-static void calc(void (*fn)(double x, double y, double z, bool last),
+static void inter_point(void (*fn)(double x, double y, double z, bool last),
const struct vertex *va, const struct vertex *vb, double t, bool last)
{
double dx, dy, dz;
@@ -148,6 +152,8 @@ static void calc(void (*fn)(double x, double y, double z, bool last),
}
+/* --- Needle step --- */
+
/*
* Known bug: we don't take into account horizontal needle deflection.
* E.g., when slightly beyond a vertical drop, the needle may bend as
@@ -163,17 +169,14 @@ static void calc(void (*fn)(double x, double y, double z, bool last),
#define NEEDLE_SIDE 14 /* dy = 14 * dx */
-static void step(void (*fn)(double x, double y, double z, bool last),
- const struct vertex *va, const struct vertex *vb, bool last)
+static double step_calc(const struct vertex *va, const struct vertex *vb)
{
static unsigned warnings = 0;
double dx, dy, dz;
- double d, e, t;
+ double d, e;
- if (va->z > vb->z) {
- step(fn, vb, va, last);
- return;
- }
+ if (va->z > vb->z)
+ return 1 - step_calc(vb, va);
dx = vb->x - va->x;
dy = vb->y - va->y;
@@ -199,15 +202,26 @@ static void step(void (*fn)(double x, double y, double z, bool last),
fprintf(stderr, "...\n");
warnings++;
}
- fn(vb->x / 1000.0, vb->y / 1000.0, vb->z / 1000.0, last);
+ return 1;
} else {
- t = fabs(d) < EPSILON ? 0 : e / d;
- fn((va->x + t * dx) / 1000, (va->y + t * dy) / 1000,
- vb->z / 1000, last);
+ return fabs(d) < EPSILON ? 0 : e / d;
}
}
+static void step_point(void (*fn)(double x, double y, double z, bool last),
+ const struct vertex *va, const struct vertex *vb, double t, bool last)
+{
+ double dx, dy;
+
+ dx = vb->x - va->x;
+ dy = vb->y - va->y;
+
+ fn((va->x + t * dx) / 1000, (va->y + t * dy) / 1000, vb->z / 1000,
+ last);
+}
+
+
static void segment(void (*fn)(double x, double y, double z, bool last),
const struct vertex *va, const struct vertex *vb, const struct vertex *vc,
bool needle)
@@ -215,12 +229,16 @@ static void segment(void (*fn)(double x, double y, double z, bool last),
double tb, tc;
if (needle) {
- step(fn, va, vb, 0);
- step(fn, va, vc, 1);
+ tb = step_calc(va, vb);
+ tc = step_calc(va, vc);
+ if (tb > EPSILON || tc > EPSILON) {
+ step_point(fn, va, vb, tb, 0);
+ step_point(fn, va, vc, tc, 1);
+ }
} else {
- if (solve(va, vb, &tb) && solve(va, vc, &tc)) {
- calc(fn, va, vb, tb, 0);
- calc(fn, va, vc, tc, 1);
+ if (inter_solve(va, vb, &tb) && inter_solve(va, vc, &tc)) {
+ inter_point(fn, va, vb, tb, 0);
+ inter_point(fn, va, vc, tc, 1);
}
}
}