|
1 /* |
|
2 * LDForge: LDraw parts authoring CAD |
|
3 * Copyright (C) 2013 - 2018 Teemu Piippo |
|
4 * |
|
5 * This program is free software: you can redistribute it and/or modify |
|
6 * it under the terms of the GNU General Public License as published by |
|
7 * the Free Software Foundation, either version 3 of the License, or |
|
8 * (at your option) any later version. |
|
9 * |
|
10 * This program is distributed in the hope that it will be useful, |
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 * GNU General Public License for more details. |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License |
|
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
17 */ |
|
18 |
|
19 #include "plane.h" |
|
20 |
|
21 /* |
|
22 * Constructs a plane from three points |
|
23 */ |
|
24 Plane Plane::fromPoints(const Vertex& v1, const Vertex& v2, const Vertex& v3) |
|
25 { |
|
26 Plane result; |
|
27 result.normal = QVector3D::crossProduct(v2 - v1, v3 - v1); |
|
28 result.point = v1; |
|
29 return result; |
|
30 } |
|
31 |
|
32 /* |
|
33 * Returns whether or not this plane is valid. |
|
34 */ |
|
35 bool Plane::isValid() const |
|
36 { |
|
37 return not normal.isNull(); |
|
38 } |
|
39 |
|
40 /* |
|
41 * Finds the intersection of a line and a plane. Returns a structure containing whether or not |
|
42 * there was an intersection as well as the intersected vertex if there was one. Can return a point |
|
43 * outside of the line segment. |
|
44 * |
|
45 * C.f. https://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection#Algebraic_form |
|
46 */ |
|
47 Plane::IntersectionResult Plane::intersection(const Line& line) const |
|
48 { |
|
49 if (isValid()) |
|
50 { |
|
51 QVector3D lineVector = line.v_2 - line.v_1; |
|
52 qreal dot = QVector3D::dotProduct(lineVector, normal); |
|
53 |
|
54 if (not qFuzzyCompare(dot, 0.0)) |
|
55 { |
|
56 qreal factor = QVector3D::dotProduct(point - line.v_1, normal) / dot; |
|
57 IntersectionResult result; |
|
58 result.intersected = true; |
|
59 result.vertex = Vertex::fromVector(lineVector * factor + (line.v_1 - Vertex {0, 0, 0})); |
|
60 return result; |
|
61 } |
|
62 else |
|
63 { |
|
64 // did not intersect |
|
65 return {}; |
|
66 } |
|
67 } |
|
68 else |
|
69 { |
|
70 // plane is invalid |
|
71 return {}; |
|
72 } |
|
73 } |