aboutsummaryrefslogtreecommitdiff
path: root/geom.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'geom.hpp')
-rw-r--r--geom.hpp63
1 files changed, 31 insertions, 32 deletions
diff --git a/geom.hpp b/geom.hpp
index 0b07bdd..daeedaa 100644
--- a/geom.hpp
+++ b/geom.hpp
@@ -2,6 +2,9 @@
#include <math.h>
+#define EPSILON 1e-6
+#define abs(x) ((x)<0?-(x):(x))
+
struct vec {
double x, y;
@@ -10,6 +13,9 @@ struct vec {
double norm() const {
return sqrt(x*x + y*y);
}
+ double sqnorm() const {
+ return x*x + y*y;
+ }
double sqnorm() const {
return x*x + y*y;
@@ -27,33 +33,20 @@ struct vec {
}
bool is_nil() const {
- return x == 0 && y == 0;
- }
-
- vec operator+ (const vec& o) const {
- return vec(x + o.x, y + o.y);
- }
- vec operator- (const vec& o) const {
- return vec(x - o.x, y - o.y);
- }
- vec operator* (double m) const {
- return vec(m * x, m * y);
- }
- vec operator/ (double m) const {
- return vec(m / x, m / y);
+ return sqnorm() < EPSILON;
}
static vec from_polar(double r, double theta) {
return vec(r * cos(theta), r * sin(theta));
}
- static vec dot(vec a, vec b) { // dot product (produit scalaire)
+ static double dot(vec a, vec b) { // dot product (produit scalaire)
return a.x * b.x + a.y * b.y;
}
- static vec cross(vec a, vec b) { // cross product (déterminant 2x2)
+ static double cross(vec a, vec b) { // cross product (déterminant 2x2)
return a.x * b.y - a.y * b.x;
}
- static vec angle(vec a, vec b) { // oriented angle between two vectors
+ static double angle(vec a, vec b) { // oriented angle between two vectors
if (a.is_nil() || b.is_nil()) return 0;
float cos = dot(a.normalize(), b.normalize());
if (cos <= -1) return M_PI;
@@ -66,6 +59,13 @@ struct vec {
}
};
+inline vec operator+(const vec& a, const vec& b) { return vec(a.x+b.x, a.y+b.y); }
+inline vec operator-(const vec& a, const vec& b) { return vec(a.x-b.x, a.y-b.y); }
+inline vec operator-(const vec& a) { return vec(-a.x, -a.y); }
+inline vec operator*(double a, const vec& v) { return vec(a*v.x, a*v.y); }
+inline vec operator*(const vec& v, double a) { return vec(a*v.x, a*v.y); }
+inline vec operator/(const vec& v, double a) { return vec(v.x/a, v.y/a); }
+
struct line {
// Line defined by ax + by + c = 0
double a, b, c;
@@ -78,21 +78,21 @@ struct line {
}
bool on_line(vec p) const {
- return a * p.x + b * p.y + c == 0;
+ return a * p.x + b * p.y + c < EPSILON;
}
double dist(vec p) const {
// calculate distance from p to the line
- return abs(a*p.x+b*p.y+c)/sqrt(a*a+b*b);
+ return abs(a*p.x + b*p.y + c) / sqrt(a*a + b*b);
}
- vec dir() const {
+ vec dir() const {
// calculate a directional vector oh the line
return vec(-b,a);
- }
+ }
vec proj(vec p) const {
// calculate orthogonal projection of point p on the line
- return p-(a*p.x+b*p.y+c)/(a*a+b*b)*vec(a,b);
+ return p-(a*p.x+b*p.y+c)/(a*a+b*b)*vec(a,b);
}
double angle() const {
@@ -108,18 +108,17 @@ struct segment {
bool on_segment(vec p) const {
// TODO
-
+
// does point intersect segment?
return false;
}
double dist(vec p) const {
- double scal = vec::dot(b-a, p-a);
- double sqn = (b-a).sqnorm
- if(scal > sqn)return (p-b).norm ;
- if(scal < 0) return (p-a).norm ;
- return line(a,b).dist(p);
- return 1;
+ double scal = vec::dot(b-a, p-a);
+ double sqn = (b-a).sqnorm
+ if(scal > sqn)return (p-b).norm ;
+ if(scal < 0) return (p-a).norm ;
+ return line(a,b).dist(p);
}
};
@@ -130,8 +129,8 @@ struct circle {
circle(double x, double y, double rr) : c(x, y), r(rr) {}
circle(vec cc, double rr) : c(cc), r(rr) {}
- bool on_circle(vec.p) const {
- return ((p - c).norm() == r);
+ bool on_circle(vec p) const {
+ return ((p - c).norm() - r < EPSILON);
}
double dist(vec p) const {
@@ -145,7 +144,7 @@ struct circpoint {
double theta;
circpoint(circle cc, double th) : c(cc), theta(th) {}
- circpoint(vec cc, double rr, double th : c(cc, rr), theta(th) {}
+ circpoint(vec cc, double rr, double th) : c(cc, rr), theta(th) {}
vec pos() const {
return c.c + vec(c.r * cos(theta), c.r * sin(theta));