Gamp v0.0.7-36-g24b1eb6
Gamp: Graphics, Audio, Multimedia and Processing
Loading...
Searching...
No Matches
geom3f.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright Gothel Software e.K.
4 *
5 * SPDX-License-Identifier: MIT
6 *
7 * This Source Code Form is subject to the terms of the MIT License
8 * If a copy of the MIT was not distributed with this file,
9 * you can obtain one at https://opensource.org/license/mit/.
10 */
11#ifndef JAU_MATH_GEOM_GEOM3F_HPP_
12#define JAU_MATH_GEOM_GEOM3F_HPP_
13
14#include <limits>
15#include <jau/darray.hpp>
16#include <jau/math/vec3f.hpp>
19
20namespace jau::math::geom {
21
22 /** \addtogroup Math
23 *
24 * @{
25 */
26
27 struct LineSeg3f {
30
31 /**
32 * Scale this line segment with given scale factor
33 * @param s scale factor
34 * @return this instance
35 */
36 constexpr LineSeg3f& operator*=(const float s ) noexcept {
37 p0 *= s;
38 p1 *= s;
39 return *this;
40 }
41
42 std::string toString() const noexcept { return "L[" + p0.toString() + ", " + p1.toString() + "]"; }
43
44 /**
45 * Compute intersection between two lines segments
46 * @param result storage for the intersection coordinates if the lines intersect, otherwise unchanged
47 * @param a vertex 1 of first line
48 * @param b vertex 2 of first line
49 * @param c vertex 1 of second line
50 * @param d vertex 2 of second line
51 * @return true if the line segments intersect, otherwise false
52 */
53 bool intersects(Point3f& result, const LineSeg3f & o) {
54 const float determinant = ( p0.x - p1.x ) * ( o.p0.y - o.p1.y) - ( p0.y - p1.y ) * ( o.p0.x - o.p1.x );
55 if( 0 == determinant ) {
56 return false;
57 }
58 const float alpha = p0.x * p1.y - p0.y * p1.x;
59 const float beta = o.p0.x*o.p1.y-o.p0.y*o.p1.y;
60 const float xi = ((o.p0.x-o.p1.x)*alpha-(p0.x-p1.x)*beta)/determinant;
61
62 const float gamma0 = (xi - p0.x) / (p1.x - p0.x);
63 const float gamma1 = (xi - o.p0.x) / (o.p1.x - o.p0.x);
64 if(gamma0 <= 0 || gamma0 >= 1 || gamma1 <= 0 || gamma1 >= 1) {
65 return false;
66 }
67 const float yi = ((o.p0.y-o.p1.y)*alpha-(p0.y-p1.y)*beta)/determinant;
68 result.x = xi;
69 result.y = yi;
70 return true;
71 }
72
73 /**
74 * Compute intersection between two lines segments
75 * @param a vertex 1 of first line
76 * @param b vertex 2 of first line
77 * @param c vertex 1 of second line
78 * @param d vertex 2 of second line
79 * @return true if the line segments intersect, otherwise false
80 */
81 bool intersects(const LineSeg3f & o) {
82 const float determinant = ( p0.x - p1.x ) * ( o.p0.y - o.p1.y) - ( p0.y - p1.y ) * ( o.p0.x - o.p1.x );
83 if( 0 == determinant ) {
84 return false;
85 }
86 const float alpha = p0.x * p1.y - p0.y * p1.x;
87 const float beta = o.p0.x*o.p1.y-o.p0.y*o.p1.y;
88 const float xi = ((o.p0.x-o.p1.x)*alpha-(p0.x-p1.x)*beta)/determinant;
89
90 const float gamma0 = (xi - p0.x) / (p1.x - p0.x);
91 const float gamma1 = (xi - o.p0.x) / (o.p1.x - o.p0.x);
92 if(gamma0 <= 0 || gamma0 >= 1 || gamma1 <= 0 || gamma1 >= 1) {
93 return false;
94 }
95 return true;
96 }
97
98 bool intersects(const AABBox3f& box) const noexcept {
99 // separating axis theorem.
100 const Vec3f d = (p1 - p0) * 0.5f; // half lineseg direction
101 const Vec3f e = (box.high() - box.low()) * 0.5f;
102 const Vec3f aabb_center = (box.low() + box.high()) * 0.5f;
103 const Vec3f lseg_center = p0 + d;
104 const Vec3f c = lseg_center - aabb_center;
105 Vec3f ad(std::abs(d.x), std::abs(d.y), std::abs(d.z));
106 if (std::abs(c.x) > e.x + ad.x)
107 return false;
108 if (std::abs(c.y) > e.y + ad.y)
109 return false;
110 if (std::abs(c.z) > e.z + ad.z)
111 return false;
112 if (std::abs(d.y * c.z - d.z * c.y) > e.y * ad.z + e.z * ad.y + std::numeric_limits<float>::epsilon()) {
113 return false;
114 }
115 if (std::abs(d.z * c.x - d.x * c.z) > e.z * ad.x + e.x * ad.z + std::numeric_limits<float>::epsilon()) {
116 return false;
117 }
118 if (std::abs(d.x * c.y - d.y * c.x) > e.x * ad.y + e.y * ad.x + std::numeric_limits<float>::epsilon()) {
119 return false;
120 }
121 return true;
122 }
123
124 };
125
126 constexpr Vec3f midpoint(const Vec3f& a, const Vec3f& b) noexcept {
127 Vec3f r(a); (r+=b)*=0.5f; return r;
128 }
129
130 /**
131 * Check if one of three vertices are in triangle using barycentric coordinates computation.
132 * @param a first triangle vertex
133 * @param b second triangle vertex
134 * @param c third triangle vertex
135 * @param p1 the vertex in question
136 * @param p2 the vertex in question
137 * @param p3 the vertex in question
138 * @return true if p1 or p2 or p3 is in triangle (a, b, c), false otherwise.
139 */
140 constexpr bool isInTriangle3(const Vec3f& a, const Vec3f& b, const Vec3f& c,
141 const Vec3f& p1, const Vec3f& p2, const Vec3f& p3) noexcept
142 {
143 // Compute vectors
144 Vec3f ac = c - a; // v0
145 Vec3f ab = b - a; // v1
146
147 // Compute dot products
148 const float dotAC_AC = ac.dot(ac);
149 const float dotAC_AB = ac.dot(ab);
150 const float dotAB_AB = ab.dot(ab);
151
152 // Compute barycentric coordinates
153 const float invDenom = 1 / (dotAC_AC * dotAB_AB - dotAC_AB * dotAC_AB);
154 {
155 Vec3f ap = p1 - a; // v2
156 const float dotAC_AP1 = ac.dot(ap);
157 const float dotAB_AP1 = ab.dot(ap);
158 const float u = (dotAB_AB * dotAC_AP1 - dotAC_AB * dotAB_AP1) * invDenom;
159 const float v = (dotAC_AC * dotAB_AP1 - dotAC_AB * dotAC_AP1) * invDenom;
160
161 // Check if point is in triangle
162 if ( (u >= 0) && (v >= 0) && (u + v < 1) ) {
163 return true;
164 }
165 }
166
167 {
168 Vec3f ap = p2 - a; // v2
169 const float dotAC_AP2 = ac.dot(ap);
170 const float dotAB_AP2 = ab.dot(ap);
171 const float u = (dotAB_AB * dotAC_AP2 - dotAC_AB * dotAB_AP2) * invDenom;
172 const float v = (dotAC_AC * dotAB_AP2 - dotAC_AB * dotAC_AP2) * invDenom;
173
174 // Check if point is in triangle
175 if ( (u >= 0) && (v >= 0) && (u + v < 1) ) {
176 return true;
177 }
178 }
179
180 {
181 Vec3f ap = p3 - a; // v3
182 const float dotAC_AP3 = ac.dot(ap);
183 const float dotAB_AP3 = ab.dot(ap);
184 const float u = (dotAB_AB * dotAC_AP3 - dotAC_AB * dotAB_AP3) * invDenom;
185 const float v = (dotAC_AC * dotAB_AP3 - dotAC_AB * dotAC_AP3) * invDenom;
186
187 // Check if point is in triangle
188 if ( (u >= 0) && (v >= 0) && (u + v < 1) ) {
189 return true;
190 }
191 }
192 return false;
193 }
194
195 /**@}*/
196
197} // namespace jau::math::geom
198
199#endif /* JAU_MATH_GEOM_GEOM3F_HPP_ */
value_type x
Definition vec3f.hpp:69
constexpr value_type dot(const Vector3F &o) const noexcept
Return the dot product of this vector and the given one.
Definition vec3f.hpp:302
value_type y
Definition vec3f.hpp:70
value_type z
Definition vec3f.hpp:71
Axis Aligned Bounding Box.
Definition aabbox3f.hpp:43
constexpr Vec3f midpoint(const Vec3f &a, const Vec3f &b) noexcept
Definition geom3f.hpp:126
Vector3F< float > Vec3f
Definition vec3f.hpp:436
Point3F< float > Point3f
Definition vec3f.hpp:451
constexpr bool isInTriangle3(const Vec3f &a, const Vec3f &b, const Vec3f &c, const Vec3f &p1, const Vec3f &p2, const Vec3f &p3) noexcept
Check if one of three vertices are in triangle using barycentric coordinates computation.
Definition geom3f.hpp:140
bool intersects(const AABBox3f &box) const noexcept
Definition geom3f.hpp:98
constexpr LineSeg3f & operator*=(const float s) noexcept
Scale this line segment with given scale factor.
Definition geom3f.hpp:36
bool intersects(Point3f &result, const LineSeg3f &o)
Compute intersection between two lines segments.
Definition geom3f.hpp:53
std::string toString() const noexcept
Definition geom3f.hpp:42
bool intersects(const LineSeg3f &o)
Compute intersection between two lines segments.
Definition geom3f.hpp:81