summaryrefslogtreecommitdiff
path: root/meme/plane.c
diff options
context:
space:
mode:
authorWerner Almesberger <werner@almesberger.net>2014-09-12 22:03:30 (GMT)
committerWerner Almesberger <werner@almesberger.net>2014-09-12 22:03:30 (GMT)
commit2cff1edad1a3ff6e4379ec90602c276a1a27dd51 (patch)
treed1fe37a9105cbcb9a35ef4798cf6c2d718a06436 /meme/plane.c
parent7b7435012f7e510e08662463b0865327824e2ab9 (diff)
downloadmisc-2cff1edad1a3ff6e4379ec90602c276a1a27dd51.zip
misc-2cff1edad1a3ff6e4379ec90602c276a1a27dd51.tar.gz
misc-2cff1edad1a3ff6e4379ec90602c276a1a27dd51.tar.bz2
meme/: show intersection with XZ plane (WIP)
Doesn't look quite right yet. Also, there are rendering errors.
Diffstat (limited to 'meme/plane.c')
-rw-r--r--meme/plane.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/meme/plane.c b/meme/plane.c
new file mode 100644
index 0000000..1a9b7ce
--- /dev/null
+++ b/meme/plane.c
@@ -0,0 +1,100 @@
+/*
+ * plane.c - Intersect mesh with planes
+ *
+ * Written 2014 by Werner Almesberger
+ * Copyright 2014 by Werner Almesberger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "mesh.h"
+#include "plane.h"
+
+
+#define ALLOC 1024 /* must be power of two */
+
+
+struct cut {
+ int coord;
+ struct point *res;
+ unsigned n;
+};
+
+
+static void add_point(struct cut *cut, int x, int y)
+{
+ struct point *p;
+
+ if (!cut->res)
+ cut->res = calloc(ALLOC, sizeof(struct point *));
+
+ /* this tests if we're at a 2^n boundary */
+ if (cut->n >= ALLOC && (cut->n & (cut->n - 1)) == 0)
+ cut->res = realloc(cut->res,
+ cut->n * 2 * sizeof(struct point *));
+ p = &cut->res[cut->n];
+ p->x = x;
+ p->y = y;
+ cut->n++;
+}
+
+
+static bool cut_xz(const struct vertex *a, const struct vertex *b, void *user)
+{
+ struct cut *cut = user;
+ int y = cut->coord;
+ int dx, dy, dz;
+ float fx, fz;;
+
+ if ((a->y > y || b->y < y) && (a->y < y || b->y > y))
+ return 0;
+
+ if (a->y == b->y) {
+ add_point(cut, (a->x + b->x) / 2, (a->z + b->z) / 2);
+ return 0;
+ }
+
+ dx = a->x - b->x;
+ dy = a->y - b->y;
+ dz = a->z - b->z;
+ fx = dx/(float) dy;
+ fz = dz/(float) dy;
+ add_point(cut, b->x + fx * dx, b->z + fz * dz);
+
+ return 0;
+}
+
+
+static int comp_x(const void *a, const void *b)
+{
+ const struct point *pa = a;
+ const struct point *pb = b;
+
+ if (pa->x < pb->x)
+ return -1;
+ if (pa->x > pb->x)
+ return 1;
+ return 0;
+}
+
+
+struct point *plane_xz(int y, unsigned *n)
+{
+ struct cut cut = {
+ .coord = y,
+ .res = NULL,
+ .n = 0,
+ };
+
+ edge_foreach(cut_xz, &cut);
+ qsort(cut.res, cut.n, sizeof(struct point *), comp_x);
+ *n = cut.n-1;
+ return cut.res;
+}