From c853ffb5b2f75f5a889ed2e3ef89b818a736e87a Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 13:50:49 +0200 Subject: Adding upstream version 1.3+ds. Signed-off-by: Daniel Baumann --- src/3rdparty/autotrace/vector.c | 260 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 src/3rdparty/autotrace/vector.c (limited to 'src/3rdparty/autotrace/vector.c') diff --git a/src/3rdparty/autotrace/vector.c b/src/3rdparty/autotrace/vector.c new file mode 100644 index 0000000..2b6375a --- /dev/null +++ b/src/3rdparty/autotrace/vector.c @@ -0,0 +1,260 @@ +/* vector.c: vector/point operations. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* Def: HAVE_CONFIG_H */ + +#include "vector.h" +#include "logreport.h" +#include "epsilon-equal.h" +#include +#include +#include +#include + +static gfloat acos_d(gfloat, at_exception_type * excep); + +#define _USE_MATH_DEFINES +#include + +/* Given the point COORD, return the corresponding vector. */ + +vector_type make_vector(const at_real_coord c) +{ + vector_type v; + + v.dx = c.x; + v.dy = c.y; + v.dz = c.z; + + return v; +} + +/* And the converse: given a vector, return the corresponding point. */ + +at_real_coord vector_to_point(const vector_type v) +{ + at_real_coord coord; + + coord.x = v.dx; + coord.y = v.dy; + + return coord; +} + +gfloat magnitude(const vector_type v) +{ + return (gfloat) sqrt(v.dx * v.dx + v.dy * v.dy + v.dz * v.dz); +} + +vector_type normalize(const vector_type v) +{ + vector_type new_v; + gfloat m = magnitude(v); + + /* assert (m > 0.0); */ + + if (m > 0.0) { + new_v.dx = v.dx / m; + new_v.dy = v.dy / m; + new_v.dz = v.dz / m; + } else { + new_v.dx = v.dx; + new_v.dy = v.dy; + new_v.dz = v.dz; + } + + return new_v; +} + +vector_type Vadd(const vector_type v1, const vector_type v2) +{ + vector_type new_v; + + new_v.dx = v1.dx + v2.dx; + new_v.dy = v1.dy + v2.dy; + new_v.dz = v1.dz + v2.dz; + + return new_v; +} + +gfloat Vdot(const vector_type v1, const vector_type v2) +{ + return v1.dx * v2.dx + v1.dy * v2.dy + v1.dz * v2.dz; +} + +vector_type Vmult_scalar(const vector_type v, const gfloat r) +{ + vector_type new_v; + + new_v.dx = v.dx * r; + new_v.dy = v.dy * r; + new_v.dz = v.dz * r; + + return new_v; +} + +/* Given the IN_VECTOR and OUT_VECTOR, return the angle between them in + degrees, in the range zero to 180. */ + +gfloat Vangle(const vector_type in_vector, const vector_type out_vector, at_exception_type * exp) +{ + vector_type v1 = normalize(in_vector); + vector_type v2 = normalize(out_vector); + + return acos_d(Vdot(v2, v1), exp); +} + +at_real_coord Vadd_point(const at_real_coord c, const vector_type v) +{ + at_real_coord new_c; + + new_c.x = c.x + v.dx; + new_c.y = c.y + v.dy; + new_c.z = c.z + v.dz; + return new_c; +} + +at_real_coord Vsubtract_point(const at_real_coord c, const vector_type v) +{ + at_real_coord new_c; + + new_c.x = c.x - v.dx; + new_c.y = c.y - v.dy; + new_c.z = c.z - v.dz; + return new_c; +} + +at_coord Vadd_int_point(const at_coord c, const vector_type v) +{ + at_coord a; + + a.x = (unsigned short)lround((gfloat) c.x + v.dx); + a.y = (unsigned short)lround((gfloat) c.y + v.dy); + return a; +} + +vector_type Vabs(const vector_type v) +{ + vector_type new_v; + + new_v.dx = (gfloat) fabs(v.dx); + new_v.dy = (gfloat) fabs(v.dy); + new_v.dz = (gfloat) fabs(v.dz); + return new_v; +} + +/* Operations on points. */ + +at_real_coord Padd(const at_real_coord coord1, const at_real_coord coord2) +{ + at_real_coord sum; + + sum.x = coord1.x + coord2.x; + sum.y = coord1.y + coord2.y; + sum.z = coord1.z + coord2.z; + + return sum; +} + +at_real_coord Pmult_scalar(const at_real_coord coord, const gfloat r) +{ + at_real_coord answer; + + answer.x = coord.x * r; + answer.y = coord.y * r; + answer.z = coord.z * r; + + return answer; +} + +vector_type Psubtract(const at_real_coord c1, const at_real_coord c2) +{ + vector_type v; + + v.dx = c1.x - c2.x; + v.dy = c1.y - c2.y; + v.dz = c1.z - c2.z; + + return v; +} + +/* Operations on integer points. */ + +vector_type IPsubtract(const at_coord coord1, const at_coord coord2) +{ + vector_type v; + + v.dx = (gfloat) (coord1.x - coord2.x); + v.dy = (gfloat) (coord1.y - coord2.y); + v.dz = 0.0; + + return v; +} + +at_coord IPsubtractP(const at_coord c1, const at_coord c2) +{ + at_coord c; + + c.x = c1.x - c2.x; + c.y = c1.y - c2.y; + + return c; +} + +at_coord IPadd(const at_coord c1, const at_coord c2) +{ + at_coord c; + + c.x = c1.x + c2.x; + c.y = c1.y + c2.y; + + return c; +} + +at_coord IPmult_scalar(const at_coord c, const int i) +{ + at_coord a; + + a.x = (unsigned short)(c.x * i); + a.y = (unsigned short)(c.y * i); + + return a; +} + +at_real_coord IPmult_real(const at_coord c, const gfloat r) +{ + at_real_coord a; + + a.x = c.x * r; + a.y = c.y * r; + + return a; +} + +gboolean IPequal(const at_coord c1, const at_coord c2) +{ + if ((c1.x == c2.x) && (c1.y == c2.y)) + return TRUE; + else + return FALSE; +} + +static gfloat acos_d(gfloat v, at_exception_type * excep) +{ + gfloat a; + + if (epsilon_equal(v, 1.0)) + v = 1.0; + else if (epsilon_equal(v, -1.0)) + v = -1.0; + + errno = 0; + a = (gfloat) acos(v); + if (errno == ERANGE || errno == EDOM) { + at_exception_fatal(excep, strerror(errno)); + return 0.0; + } + + return a * (gfloat) 180.0 / (gfloat) M_PI; +} -- cgit v1.2.3