|
|
|
@ -2,17 +2,10 @@
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include "point.h"
|
|
|
|
|
|
|
|
|
|
// scale vector to length
|
|
|
|
|
struct point pt_scale(struct point pt, double length) {
|
|
|
|
|
double f = length / pt_length(pt);
|
|
|
|
|
return (struct point) {
|
|
|
|
|
.x = pt.x * f,
|
|
|
|
|
.y = pt.y * f,
|
|
|
|
|
.z = pt.z * f
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
// get the length of vector
|
|
|
|
|
inline double pt_length_inline (struct point pt) __attribute__((always_inline));
|
|
|
|
|
|
|
|
|
|
struct point pt_mult(struct point pt, double scalar) {
|
|
|
|
|
inline struct point pt_mult(struct point pt, double scalar) {
|
|
|
|
|
return (struct point) {
|
|
|
|
|
.x = pt.x * scalar,
|
|
|
|
|
.y = pt.y * scalar,
|
|
|
|
@ -21,7 +14,7 @@ struct point pt_mult(struct point pt, double scalar) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// return internal angle between a and b
|
|
|
|
|
double pt_angle(struct point a, struct point b) {
|
|
|
|
|
inline double pt_angle(struct point a, struct point b) {
|
|
|
|
|
return acos(pt_dot(
|
|
|
|
|
pt_normalize(a),
|
|
|
|
|
pt_normalize(b)
|
|
|
|
@ -29,12 +22,16 @@ double pt_angle(struct point a, struct point b) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// get the length of vector
|
|
|
|
|
double pt_length(struct point pt) {
|
|
|
|
|
inline double pt_length_inline (struct point pt) {
|
|
|
|
|
return sqrt((pt.x * pt.x) + (pt.y * pt.y) + (pt.z * pt.z));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double pt_length(struct point pt) {
|
|
|
|
|
return pt_length_inline(pt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// add the vector add to the vector pt
|
|
|
|
|
struct point pt_add(struct point pt, struct point add) {
|
|
|
|
|
inline struct point pt_add(struct point pt, struct point add) {
|
|
|
|
|
return (struct point) {
|
|
|
|
|
.x = pt.x + add.x,
|
|
|
|
|
.y = pt.y + add.y,
|
|
|
|
@ -43,7 +40,7 @@ struct point pt_add(struct point pt, struct point add) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// add the vector add to the vector pt
|
|
|
|
|
struct point pt_sub(struct point pt, struct point sub) {
|
|
|
|
|
inline struct point pt_sub(struct point pt, struct point sub) {
|
|
|
|
|
return (struct point) {
|
|
|
|
|
.x = pt.x - sub.x,
|
|
|
|
|
.y = pt.y - sub.y,
|
|
|
|
@ -51,22 +48,38 @@ struct point pt_sub(struct point pt, struct point sub) {
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double pt_dist(struct point p1, struct point p2) {
|
|
|
|
|
return pt_length(pt_sub(p1, p2));
|
|
|
|
|
inline double pt_dist(struct point p1, struct point p2) {
|
|
|
|
|
return pt_length_inline(pt_sub(p1, p2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// normalize a vector
|
|
|
|
|
struct point pt_normalize(struct point pt) {
|
|
|
|
|
return pt_scale(pt, 1);
|
|
|
|
|
inline struct point pt_normalize(struct point pt) {
|
|
|
|
|
double length = pt_length(pt);
|
|
|
|
|
|
|
|
|
|
return (struct point) {
|
|
|
|
|
.x = pt.x / length,
|
|
|
|
|
.y = pt.y / length,
|
|
|
|
|
.z = pt.z / length
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// scale vector to length
|
|
|
|
|
inline struct point pt_scale(struct point pt, double length) {
|
|
|
|
|
double f = length / pt_length_inline(pt);
|
|
|
|
|
return (struct point) {
|
|
|
|
|
.x = pt.x * f,
|
|
|
|
|
.y = pt.y * f,
|
|
|
|
|
.z = pt.z * f
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// dot product of two vectors
|
|
|
|
|
double pt_dot(struct point a, struct point b) {
|
|
|
|
|
inline double pt_dot(struct point a, struct point b) {
|
|
|
|
|
return a.x*b.x + a.y*b.y + a.z*b.z;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// cross product of two vectors
|
|
|
|
|
struct point pt_cross(struct point a, struct point b) {
|
|
|
|
|
inline struct point pt_cross(struct point a, struct point b) {
|
|
|
|
|
return (struct point) {
|
|
|
|
|
.x = a.y*b.z - a.z*b.y,
|
|
|
|
|
.y = a.z*b.x - a.x*b.z,
|
|
|
|
@ -74,29 +87,29 @@ struct point pt_cross(struct point a, struct point b) {
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void pt_print(struct point pt) {
|
|
|
|
|
inline void pt_print(struct point pt) {
|
|
|
|
|
printf("(%f, %f, %f)\n", pt.x, pt.y, pt.z);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void pt_print_n(const char* name, struct point pt) {
|
|
|
|
|
inline void pt_print_n(const char* name, struct point pt) {
|
|
|
|
|
printf("%s: (%f, %f, %f)\n", name, pt.x, pt.y, pt.z);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// find two vectors that span the orthogonal plane, where
|
|
|
|
|
// span_xy is a vector lying on the xy-plane (and pointing left)
|
|
|
|
|
// and span_z is orthogonal to span_xy pointing "upwards"
|
|
|
|
|
void pt_orthogonal_plane(struct point pt, struct point *span_z, struct point *span_xy) {
|
|
|
|
|
inline void pt_orthogonal_plane(struct point pt, struct point *span_z, struct point *span_xy) {
|
|
|
|
|
pt = pt_normalize(pt);
|
|
|
|
|
|
|
|
|
|
// get the vector lying on the xy axis
|
|
|
|
|
// this is done by
|
|
|
|
|
*span_xy = pt_normalize(pt_cross((struct point){.x = 0, .y = 0, .z = 1}, pt)); // points to the "left" (of the viewing direction)
|
|
|
|
|
// this is done by
|
|
|
|
|
*span_xy = pt_normalize(pt_cross(PT_NEW(0,0,1), pt)); // points to the "left" (of the viewing direction)
|
|
|
|
|
|
|
|
|
|
// now use this, to find the vector
|
|
|
|
|
*span_z = pt_normalize(pt_cross(pt, *span_xy));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct point pt_mod(struct point pt, double mod) {
|
|
|
|
|
inline struct point pt_mod(struct point pt, double mod) {
|
|
|
|
|
return (struct point) {
|
|
|
|
|
.x = fabs(fmod(pt.x, mod)),
|
|
|
|
|
.y = fabs(fmod(pt.y, mod)),
|
|
|
|
|