-
Notifications
You must be signed in to change notification settings - Fork 0
/
3d.cpp
109 lines (98 loc) · 2.82 KB
/
3d.cpp
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
// typedef ll cod;
// bool eq(cod a, cod b){ return (a==b); }
const ld EPS = 1e-6;
#define vp vector<point>
typedef ld cod;
bool eq(cod a, cod b){ return fabs(a - b) <= EPS; }
struct point
{
cod x, y, z;
point(cod x=0, cod y=0, cod z=0): x(x), y(y), z(z) {}
point operator+(const point &o) const {
return {x+o.x, y+o.y, z+o.z};
}
point operator-(const point &o) const {
return {x-o.x, y-o.y, z-o.z};
}
point operator*(cod t) const {
return {x*t, y*t, z*t};
}
point operator/(cod t) const {
return {x/t, y/t, z/t};
}
bool operator==(const point &o) const {
return eq(x, o.x) and eq(y, o.y) and eq(z, o.z);
}
cod operator*(const point &o) const { // dot
return x*o.x + y*o.y + z*o.z;
}
point operator^(const point &o) const { // cross
return point(y*o.z - z*o.y,
z*o.x - x*o.z,
x*o.y - y*o.x);
}
};
ld norm(point a) { // Modulo
return sqrt(a * a);
}
cod norm2(point a) {
return a * a;
}
bool nulo(point a) {
return (eq(a.x, 0) and eq(a.y, 0) and eq(a.z, 0));
}
ld proj(point a, point b) { // a sobre b
return (a*b)/norm(b);
}
ld angle(point a, point b) { // em radianos
return acos((a*b) / norm(a) / norm(b));
}
cod triple(point a, point b, point c) {
return (a * (b^c)); // Area do paralelepipedo
}
point normilize(point a) {
return a/norm(a);
}
struct plane {
cod a, b, c, d;
point p1, p2, p3;
plane(point p1=0, point p2=0, point p3=0): p1(p1), p2(p2), p3(p3) {
point aux = (p1-p3)^(p2-p3);
a = aux.x; b = aux.y; c = aux.z;
d = -a*p1.x - b*p1.y - c*p1.z;
}
plane(point p, point normal) {
normal = normilize(normal);
a = normal.x; b = normal.y; c = normal.z;
d = -(p*normal);
}
// ax+by+cz+d = 0;
cod eval(point &p) {
return a*p.x + b*p.y + c*p.z + d;
}
};
cod dist(plane pl, point p) {
return fabs(pl.a*p.x + pl.b*p.y + pl.c*p.z + pl.d) / sqrt(pl.a*pl.a + pl.b*pl.b + pl.c*pl.c);
}
point rotate(point v, point k, ld theta) {
// Rotaciona o vetor v theta graus em torno do eixo k
// theta *= PI/180; // graus
return (
v*cos(theta)) +
((k^v)*sin(theta)) +
(k*(k*v))*(1-cos(theta)
);
}
// 3d line inter / mindistance
cod d(point p1, point p2, point p3, point p4) {
return (p2-p1) * (p4-p3);
}
vector<point> inter3d(point p1, point p2, point p3, point p4) {
cod mua = ( d(p1, p3, p4, p3) * d(p4, p3, p2, p1) - d(p1, p3, p2, p1) * d(p4, p3, p4, p3) )
/ ( d(p2, p1, p2, p1) * d(p4, p3, p4, p3) - d(p4, p3, p2, p1) * d(p4, p3, p2, p1) );
cod mub = ( d(p1, p3, p4, p3) + mua * d(p4, p3, p2, p1) ) / d(p4, p3, p4, p3);
point pa = p1 + (p2-p1) * mua;
point pb = p3 + (p4-p3) * mub;
if (pa == pb) return {pa};
return {};
}