-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path1605067_geometry.h
124 lines (102 loc) · 3.64 KB
/
1605067_geometry.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#ifndef __GEOMETRY_H__
#define __GEOMETRY_H__
#include <cmath>
#include <cassert>
namespace Geometry {
const double PI = acos(-1), EPS = 1e-6;
int dcmp(double x) { return abs(x) < EPS ? 0 : (x<0 ? -1 : 1);}
double degreeToRadian(double rad) { return rad*PI/180; }
struct Point {
double x, y, z;
Point() : x(0), y(0), z(0) {}
Point(double X, double Y, double Z) : x(X), y(Y), z(Z) {}
Point operator + (const Point& u) const {
return Point(x + u.x, y + u.y, z + u.z);
}
Point operator - (const Point& u) const {
return Point(x - u.x, y - u.y, z - u.z);
}
Point operator * (const double u) const {
return Point(x * u, y * u, z * u);
}
Point operator / (const double u) const {
return Point(x / u, y / u, z / u);
}
friend std::ostream &operator << (std::ostream &os, const Point &p) {
return os << p.x << " " << p.y <<" "<<p.z;
}
friend std::istream &operator >> (std::istream &is, Point &p) {
return is >> p.x >> p.y >> p.z;
}
};
const Point Origin(0, 0, 0);
double dot(Point a, Point b) {
return a.x * b.x + a.y * b.y + a.z * b.z;
}
Point cross(Point a, Point b) {
return Point(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x);
}
double length(Point a) {
return sqrt(dot(a, a));
}
double distance(Point a, Point b) {
return length(a-b);
}
Point unit(const Point &p) {
return p/length(p);
}
// Rotate p around axis x, with angle radians.
Point rotate(Point p, Point axis, double angle) {
axis = unit(axis);
Point comp1 = p * cos(angle);
Point comp2 = axis * (1-cos(angle)) * dot(axis, p);
Point comp3 = cross(axis, p) * sin(angle);
return comp1 + comp2 + comp3;
}
struct Line {Point a, v;}; ///a+tv
// returns the distance from point a to line l
double distancePointLine(Point p, Line l) {
return length(cross(l.v, p - l.a)) / length(l.v);
}
/// distance from Line ab to Line cd
double distanceLineLine(Line a, Line b) {
Point cr = cross(a.v, b.v);
double crl = length(cr);
if (dcmp(crl) == 0) return distancePointLine(a.a, b);
return abs(dot(cr, a.a-b.a))/crl;
}
struct Plane {
Point normal; /// Normal = (A, B, C)
double d; /// dot(Normal) = d <--> Ax + By + Cz = d
Point P; /// anyPoint on the plane, optional
Plane(Point normal, double d) {
double len = length(normal);
assert(dcmp(len) > 0);
normal = normal / len;
d = d / len;
if (dcmp(normal.x)) P = Point(d/normal.x, 0, 0);
else if (dcmp(normal.y)) P = Point(0, d/normal.y, 0);
else P = Point(0, 0, d/normal.z);
}
///Plane given by three Non-Collinear Points
Plane(Point a, Point b, Point c) {
normal = unit(cross(b-a, c-a));
d = dot(normal, a);
P = a;
}
bool onPlane(Point a) {
return dcmp(dot(normal, a) - d) == 0;
}
double distance(Point a) {
return abs(dot(normal, a) - d);
}
double isParallel(Line l) {
return dcmp(dot(l.v, normal)) == 0;
}
///return t st l.a + t*l.v is a point on the plane, check parallel first
double intersectLine(Line l) {
return dot(P-l.a, normal)/dot(l.v, normal);
}
};
} // namespace Geometry
#endif // __GEOMETRY_H__