diff --git a/slicer/slice.c b/slicer/slice.c new file mode 100644 index 0000000..8022edd --- /dev/null +++ b/slicer/slice.c @@ -0,0 +1,150 @@ +/* + * slice.c - Generate slices + * + * Written 2015 by Werner Almesberger + * Copyright 2015 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 +#include +#include + +#include "util.h" +#include "stl.h" +#include "slice.h" + + +struct line { + float ax, ay; + float bx, by; + struct line *next; +}; + + +struct z { + float z; + bool present; + struct line *lines; +}; + + +static GTree *tree; + + +static inline bool eq(float a, float b) +{ + return fabsf(a - b) < 1e-6; +} + + +static struct z *get_z(float z) +{ + struct z *base; + + base = g_tree_lookup(tree, &z); + if (base) + return base; + base = alloc_type(struct z); + base->z = z; + base->present = 0; + base->lines = NULL; + g_tree_insert(tree, &base->z, base); + return base; +} + + +static void mark_z(float z) +{ + struct z *base; + + base = get_z(z); + base->present = 1; +} + + +static void add(const struct v *a, const struct v *b, const struct v *c) +{ + struct z *z; + struct line *line; + + /* @@@ should check that C is above AB */ + + if (eq(a->x, b->x) && eq(a->y, b->y)) { +fprintf(stderr, "zero point\n"); + return; + } + z = get_z(a->z); + line = alloc_type(struct line); + line->ax = a->x; + line->ay = a->y; + line->bx = b->x; + line->by = b->y; + line->next = z->lines; + z->lines = line; +} + + +void slice(struct v f[3]) +{ + bool ab = eq(f[0].z, f[1].z); + bool bc = eq(f[1].z, f[2].z); + bool ac = eq(f[0].z, f[2].z); + + if (ab && bc) + mark_z(f[0].z); + else if (ab) + add(f + 0, f + 1, f + 2); + else if (bc) + add(f + 1, f + 2, f + 0); + else if (ac) + add(f + 0, f + 2, f + 1); +} + + +/* ----- Dumping ----------------------------------------------------------- */ + + +static gboolean dump(gpointer key, gpointer value, gpointer data) +{ + const struct z *z = value; + const struct line *line; + + if (!z->present) + return 0; + for (line = z->lines; line; line = line->next) + printf("%f %f %f\n%f %f %f\n\n\n", + line->ax, line->ay, z->z, + line->bx, line->by, z->z); + return 0; +} + + +void slice_dump(void) +{ + g_tree_foreach(tree, dump, NULL); +} + + +/* ----- Initialization ---------------------------------------------------- */ + + +static gint comp(gconstpointer a, gconstpointer b) +{ + const float *za = a; + const float *zb = b; + + return eq(*za, *zb) ? 0 : *za < *zb ? -1 : 1; + +} + + +void slice_init(void) +{ + tree = g_tree_new(comp); +} diff --git a/slicer/slice.h b/slicer/slice.h new file mode 100644 index 0000000..fbaa9ac --- /dev/null +++ b/slicer/slice.h @@ -0,0 +1,24 @@ +/* + * slice.h - Generate slices + * + * Written 2015 by Werner Almesberger + * Copyright 2015 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. + */ + + +#ifndef SLICE_H +#define SLICE_H + +#include "stl.h" + + +void slice(struct v f[3]); +void slice_dump(void); +void slice_init(void); + +#endif /* !SLICE_H */ diff --git a/slicer/util.h b/slicer/util.h new file mode 100644 index 0000000..56f4b8b --- /dev/null +++ b/slicer/util.h @@ -0,0 +1,30 @@ +/* + * util.h - Common utility functions + * + * Written 2006, 2009, 2010 by Werner Almesberger + * Copyright 2006, 2009, 2010 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. + */ + + +#ifndef UTIL_H +#define UTIL_H + +#include +#include +#include + + +#define alloc_size(s) \ + ({ void *alloc_size_tmp = malloc(s); \ + if (!alloc_size_tmp) \ + abort(); \ + alloc_size_tmp; }) + +#define alloc_type(t) ((t *) alloc_size(sizeof(t))) + +#endif /* !UTIL_H */