Skip to content

Commit 679bc23

Browse files
committed
gtx closest point
1 parent 9f5a694 commit 679bc23

File tree

5 files changed

+261
-9
lines changed

5 files changed

+261
-9
lines changed

src/main/kotlin/glm_/func/func_trigonometric.kt

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,30 @@ interface func_trigonometric {
149149
}
150150
}
151151

152-
val Float.deg get() = Math.toDegrees(this.d).f
153-
val Double.deg get() = Math.toDegrees(this)
154-
val Float.rad get() = Math.toRadians(this.d).f
155-
val Double.rad get() = Math.toRadians(this)
156-
157-
val Float.cos get() = _cos(this)
158-
val Double.cos get() = _cos(this)
159-
val Float.sin get() = _sin(this)
160-
val Double.sin get() = _sin(this)
152+
val Int.deg: Float
153+
get() = Math.toDegrees(d).f
154+
val Float.deg: Float
155+
get() = Math.toDegrees(d).f
156+
val Double.deg: Double
157+
get() = Math.toDegrees(this)
158+
159+
val Int.rad: Float
160+
get() = Math.toRadians(d).f
161+
val Float.rad: Float
162+
get() = Math.toRadians(d).f
163+
val Double.rad: Double
164+
get() = Math.toRadians(this)
165+
166+
val Int.cos: Float
167+
get() = _cos(f)
168+
val Float.cos: Float
169+
get() = _cos(this)
170+
val Double.cos: Double
171+
get() = _cos(this)
172+
173+
val Int.sin: Double
174+
get() = _sin(d)
175+
val Float.sin: Float
176+
get() = _sin(this)
177+
val Double.sin: Double
178+
get() = _sin(this)

src/main/kotlin/glm_/glm.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ object glm :
7373

7474
gtcMatrixInverse,
7575

76+
gtxClosestPoint,
7677
gtxEasing,
7778
gtxEulerAngles,
7879
gtxFastTrigonometry,
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package glm_.gtx
2+
3+
import glm_.glm
4+
import glm_.vec2.Vec2
5+
import glm_.vec3.Vec3
6+
7+
8+
interface gtxClosestPoint {
9+
10+
/** Find the point on a straight line which is the closet of a point.
11+
* @see gtx_closest_point */
12+
fun closestPointOnLine(point: Vec3, a: Vec3, b: Vec3): Vec3 {
13+
14+
val lineLength = glm.distance(a, b)
15+
val vector = point - a
16+
val lineDirection = (b - a) / lineLength
17+
18+
// Project vector to lineDirection to get the distance of point from a
19+
val distance = vector dot lineDirection
20+
21+
return when {
22+
distance <= 0f -> a
23+
distance >= lineLength -> b
24+
else -> a + lineDirection * distance
25+
}
26+
}
27+
28+
/** 2d lines work as well */
29+
fun closestPointOnLine(point: Vec2, a: Vec2, b: Vec2): Vec2 {
30+
val lineLength = glm.distance(a, b)
31+
val vector = point - a
32+
val lineDirection = (b - a) / lineLength
33+
34+
// Project vector to lineDirection to get the distance of point from a
35+
val distance = vector dot lineDirection
36+
37+
return when {
38+
distance <= 0f -> a
39+
distance >= lineLength -> b
40+
else -> a + lineDirection * distance
41+
}
42+
}
43+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package glm_.gtx
2+
3+
import glm_.glm
4+
import glm_.vec3.Vec3
5+
import io.kotlintest.shouldBe
6+
import io.kotlintest.specs.StringSpec
7+
8+
class testGtxClosestPoint : StringSpec() {
9+
10+
init {
11+
12+
"gtx Closest Point" {
13+
14+
val origin = Vec3()
15+
16+
val a = Vec3(0, 1, 0)
17+
val b = Vec3(1, 0, 0)
18+
19+
val point = glm.closestPointOnLine(origin, a, b)
20+
glm.epsilonEqual(point, Vec3(0.5f, 0.5f, 0f), Float.MIN_VALUE)
21+
}
22+
}
23+
}
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
package glm_
2+
3+
import glm_.func.cos
4+
import glm_.func.rad
5+
import glm_.func.sin
6+
import glm_.vec3.Vec3
7+
import io.kotlintest.specs.StringSpec
8+
9+
class testReflection : StringSpec() {
10+
11+
init {
12+
"custom reflection" {
13+
14+
/*
15+
viewPoint
16+
17+
18+
++
19+
+ +
20+
+ . +
21+
22+
*/
23+
24+
val degreeStep = 10
25+
val counts = 180 / degreeStep + 1
26+
val mirrorPoints = Array(counts) {
27+
val angle = (degreeStep * it).rad
28+
Vec3(angle.cos, angle.sin, 0f)
29+
}
30+
val viewPoint = Vec3(0, 2e10, 0)
31+
val reflections = Array(counts) {
32+
// viewport to mirror point
33+
val vpToMp = mirrorPoints[it] - viewPoint
34+
// mirrorPoints[it] represents automatically also the normal by definition
35+
glm.reflect(vpToMp, mirrorPoints[it]).normalize()
36+
}
37+
for (i in 0 until counts)
38+
println("mirrorPoints (${mirrorPoints[i].x}, ${mirrorPoints[i].y}, ${mirrorPoints[i].z})")
39+
for (i in 0 until counts)
40+
println("reflections (${reflections[i].x}, ${reflections[i].y}, ${reflections[i].z})")
41+
42+
run {
43+
val refls = Array(counts - 2) {
44+
floatArrayOf(
45+
mirrorPoints[it + 1].x, mirrorPoints[it + 1].y, mirrorPoints[it + 1].z,
46+
reflections[it + 1].x, reflections[it + 1].y, reflections[it + 1].z)
47+
}
48+
49+
val vvp = glm.closestPointToLines(refls)
50+
println("vvp (${vvp.x}, ${vvp.y}, ${vvp.z})")
51+
val error = Vec3()
52+
val origin = Vec3()
53+
for (i in refls.indices) {
54+
val closestPoint = glm.closestPointOnLine(vvp, origin, reflections[i + 1])
55+
val diff = vvp - closestPoint
56+
error += glm.abs(diff)
57+
}
58+
println("error (${error.x}, ${error.y}, ${error.z})")
59+
}
60+
61+
62+
println()
63+
run {
64+
val refls = Array(5) {
65+
floatArrayOf(
66+
mirrorPoints[it + 7].x, mirrorPoints[it + 7].y, mirrorPoints[it + 7].z,
67+
reflections[it + 7].x, reflections[it + 7].y, reflections[it + 7].z)
68+
}
69+
70+
val vvp = glm.closestPointToLines(refls)
71+
println("vvp (${vvp.x}, ${vvp.y}, ${vvp.z})")
72+
val error = Vec3()
73+
val origin = Vec3()
74+
for (i in refls.indices) {
75+
val closestPoint = glm.closestPointOnLine(vvp, origin, reflections[i + 7])
76+
val diff = vvp - closestPoint
77+
error += glm.abs(diff)
78+
}
79+
println("error (${error.x}, ${error.y}, ${error.z})")
80+
}
81+
println()
82+
run {
83+
val refls = Array(4) { FloatArray(6) }
84+
85+
for(i in 0..1) {
86+
87+
mirrorPoints[5 + i] to refls[i]
88+
reflections[5 + i].to(refls[i], 3)
89+
90+
mirrorPoints[12 + i] to refls[2 + i]
91+
reflections[12 + i].to(refls[2 + i], 3)
92+
}
93+
val vvp = glm.closestPointToLines(refls)
94+
println("vvp (${vvp.x}, ${vvp.y}, ${vvp.z})")
95+
val error = Vec3()
96+
val origin = Vec3()
97+
for (i in 0..1) {
98+
val closestPoint = glm.closestPointOnLine(vvp, origin, reflections[i + 5])
99+
val diff = vvp - closestPoint
100+
error += glm.abs(diff)
101+
}
102+
for (i in 0..1) {
103+
val closestPoint = glm.closestPointOnLine(vvp, origin, reflections[i + 12])
104+
val diff = vvp - closestPoint
105+
error += glm.abs(diff)
106+
}
107+
println("error (${error.x}, ${error.y}, ${error.z})")
108+
}
109+
println()
110+
run {
111+
val refls = Array(4) { FloatArray(6) }
112+
113+
for(i in 0..1) {
114+
115+
mirrorPoints[3 + i] to refls[i]
116+
reflections[3 + i].to(refls[i], 3)
117+
118+
mirrorPoints[14 + i] to refls[2 + i]
119+
reflections[14 + i].to(refls[2 + i], 3)
120+
}
121+
val vvp = glm.closestPointToLines(refls)
122+
println("vvp (${vvp.x}, ${vvp.y}, ${vvp.z})")
123+
val error = Vec3()
124+
val origin = Vec3()
125+
for (i in 0..1) {
126+
val closestPoint = glm.closestPointOnLine(vvp, origin, reflections[i + 3])
127+
val diff = vvp - closestPoint
128+
error += glm.abs(diff)
129+
}
130+
for (i in 0..1) {
131+
val closestPoint = glm.closestPointOnLine(vvp, origin, reflections[i + 14])
132+
val diff = vvp - closestPoint
133+
error += glm.abs(diff)
134+
}
135+
println("error (${error.x}, ${error.y}, ${error.z})")
136+
}
137+
println()
138+
run {
139+
val refls = Array(4) { FloatArray(6) }
140+
141+
for(i in 0..1) {
142+
143+
mirrorPoints[1 + i] to refls[i]
144+
reflections[1 + i].to(refls[i], 3)
145+
146+
mirrorPoints[16 + i] to refls[2 + i]
147+
reflections[16 + i].to(refls[2 + i], 3)
148+
}
149+
val vvp = glm.closestPointToLines(refls)
150+
println("vvp (${vvp.x}, ${vvp.y}, ${vvp.z})")
151+
val error = Vec3()
152+
val origin = Vec3()
153+
for (i in 0..1) {
154+
val closestPoint = glm.closestPointOnLine(vvp, origin, reflections[i + 1])
155+
val diff = vvp - closestPoint
156+
error += glm.abs(diff)
157+
}
158+
for (i in 0..1) {
159+
val closestPoint = glm.closestPointOnLine(vvp, origin, reflections[i + 16])
160+
val diff = vvp - closestPoint
161+
error += glm.abs(diff)
162+
}
163+
println("error (${error.x}, ${error.y}, ${error.z})")
164+
}
165+
}
166+
}
167+
}

0 commit comments

Comments
 (0)