Skip to content

Commit 7b000f2

Browse files
committed
adapt support points
1 parent 9bc5158 commit 7b000f2

File tree

1 file changed

+61
-38
lines changed

1 file changed

+61
-38
lines changed

src/Shapes/boundingBoxes.jl

Lines changed: 61 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -49,36 +49,53 @@ that is the most extreme in direction of unit vector `e`.
4949
# or Andrea Neumayr took ideas for computing based on those books
5050

5151
# [Gino v.d. Bergen, p. 135]
52-
@inline supportPoint_abs_Ellipsoid(shape::Ellipsoid, e_abs::SVector{3,T}) where {T} =
53-
@inbounds SVector( (shape.lengthX/2)^2*e_abs[1], (shape.lengthY/2)^2*e_abs[2], (shape.lengthZ/2)^2*e_abs[3] )/norm(SVector((shape.lengthX/2)*e_abs[1], (shape.lengthY/2)*e_abs[2], (shape.lengthZ/2)*e_abs[3]) )
52+
@inline function supportPoint_abs_Ellipsoid(shape::Ellipsoid, e_abs::SVector{3,T}) where {T}
53+
@inbounds begin
54+
halfLengthX = T(0.5*shape.lengthX)
55+
halfLengthY = T(0.5*shape.lengthY)
56+
halfLengthZ = T(0.5*shape.lengthZ)
57+
return SVector{3,T}( (halfLengthX)^2*e_abs[1], (halfLengthY)^2*e_abs[2], (halfLengthZ)^2*e_abs[3] )/norm(SVector{3,T}((halfLengthX)*e_abs[1], (halfLengthY)*e_abs[2], (halfLengthZ)*e_abs[3]) )
58+
end
59+
end
5460

5561
# [Gino v.d. Bergen, p. 135]
56-
@inline supportPoint_abs_Box(shape::Box, e_abs::SVector{3,T}, collisionSmoothingRadius::T) where {T} =
57-
@inbounds SVector( Basics.sign_eps(e_abs[1])*(shape.lengthX/2-collisionSmoothingRadius), Basics.sign_eps(e_abs[2])*(shape.lengthY/2-collisionSmoothingRadius), Basics.sign_eps(e_abs[3])*(shape.lengthZ/2-collisionSmoothingRadius) )
62+
@inline function supportPoint_abs_Box(shape::Box, e_abs::SVector{3,T}, collisionSmoothingRadius::T) where {T}
63+
@inbounds begin
64+
halfLengthX = T(0.5*shape.lengthX)
65+
halfLengthY = T(0.5*shape.lengthY)
66+
halfLengthZ = T(0.5*shape.lengthZ)
67+
return SVector{3,T}(
68+
Basics.sign_eps(e_abs[1])*(halfLengthX-collisionSmoothingRadius),
69+
Basics.sign_eps(e_abs[2])*(halfLengthY-collisionSmoothingRadius),
70+
Basics.sign_eps(e_abs[3])*(halfLengthZ-collisionSmoothingRadius) )
71+
end
72+
end
5873

5974
# [Gino v.d. Bergen, p. 136, XenoCollide, p. 168, 169]
6075
@inline function supportPoint_abs_Cylinder(shape::Cylinder, e_abs::SVector{3,T}) where {T}
6176
@inbounds begin
77+
halfLength = T(0.5*shape.length)
78+
halfDiameter = T(0.5*shape.diameter)
6279
if shape.axis == 1
6380
enorm = norm(SVector(e_abs[2], e_abs[3]))
6481
if enorm <= Modia3D.neps
65-
return Basics.sign_eps(e_abs[1])*SVector(shape.length/2, 0.0, 0.0)
82+
return Basics.sign_eps(e_abs[1])*SVector(halfLength, 0.0, 0.0)
6683
else
67-
return Basics.sign_eps(e_abs[1])*SVector(shape.length/2, 0.0, 0.0) + SVector(0.0, (shape.diameter/2)*e_abs[2], (shape.diameter/2)*e_abs[3])/enorm
84+
return Basics.sign_eps(e_abs[1])*SVector(halfLength, 0.0, 0.0) + SVector(0.0, (halfDiameter)*e_abs[2], (halfDiameter)*e_abs[3])/enorm
6885
end
6986
elseif shape.axis == 2
7087
enorm = norm(SVector(e_abs[3], e_abs[1]))
7188
if enorm <= Modia3D.neps
72-
return Basics.sign_eps(e_abs[2])*SVector(0.0, shape.length/2, 0.0)
89+
return Basics.sign_eps(e_abs[2])*SVector(0.0, halfLength, 0.0)
7390
else
74-
return Basics.sign_eps(e_abs[2])*SVector(0.0, shape.length/2, 0.0) + SVector((shape.diameter/2)*e_abs[1], 0.0, (shape.diameter/2)*e_abs[3])/enorm
91+
return Basics.sign_eps(e_abs[2])*SVector(0.0, halfLength, 0.0) + SVector((halfDiameter)*e_abs[1], 0.0, (halfDiameter)*e_abs[3])/enorm
7592
end
7693
else
7794
enorm = norm(SVector(e_abs[1], e_abs[2]))
7895
if enorm <= Modia3D.neps
79-
return Basics.sign_eps(e_abs[3])*SVector(0.0, 0.0, shape.length/2)
96+
return Basics.sign_eps(e_abs[3])*SVector(0.0, 0.0, halfLength)
8097
else
81-
return Basics.sign_eps(e_abs[3])*SVector(0.0, 0.0, shape.length/2) + SVector((shape.diameter/2)*e_abs[1], (shape.diameter/2)*e_abs[2], 0.0)/enorm
98+
return Basics.sign_eps(e_abs[3])*SVector(0.0, 0.0, halfLength) + SVector((halfDiameter)*e_abs[1], (halfDiameter)*e_abs[2], 0.0)/enorm
8299
end
83100
end
84101
end
@@ -87,12 +104,14 @@ end
87104
# G. Hippmann: Cylinder + Sphere as bottom and top
88105
@inline function supportPoint_abs_Capsule(shape::Capsule, e_abs::SVector{3,T}) where {T}
89106
@inbounds begin
107+
halfLength = T(0.5*shape.length)
108+
halfDiameter = T(0.5*shape.diameter)
90109
if shape.axis == 1
91-
return Basics.sign_eps(e_abs[1])*SVector(0.5*shape.length, 0.0, 0.0) + 0.5*shape.diameter*e_abs
110+
return Basics.sign_eps(e_abs[1])*SVector(halfLength, 0.0, 0.0) + halfDiameter*e_abs
92111
elseif shape.axis == 2
93-
return Basics.sign_eps(e_abs[2])*SVector(0.0, 0.5*shape.length, 0.0) + 0.5*shape.diameter*e_abs
112+
return Basics.sign_eps(e_abs[2])*SVector(0.0, halfLength, 0.0) + halfDiameter*e_abs
94113
else
95-
return Basics.sign_eps(e_abs[3])*SVector(0.0, 0.0, 0.5*shape.length) + 0.5*shape.diameter*e_abs
114+
return Basics.sign_eps(e_abs[3])*SVector(0.0, 0.0, halfLength) + halfDiameter*e_abs
96115
end
97116
end
98117
end
@@ -101,76 +120,77 @@ end
101120
# for frustum of a cone: A. Neumayr, G. Hippmann
102121
@inline function supportPoint_abs_Cone(shape::Cone, e_abs::SVector{3,T}) where {T}
103122
@inbounds begin
104-
baseRadius = shape.diameter/2
105-
rightCone = shape.topDiameter == 0.0
123+
baseRadius = T(0.5*shape.diameter)
124+
rightCone = T(shape.topDiameter) == T(0.0)
125+
shapeLength = T(shape.length)
106126
if rightCone
107-
sin_phi = baseRadius/sqrt(baseRadius^2 + shape.length^2) # sin of base angle
127+
sin_phi = T(baseRadius/sqrt(baseRadius^2 + shapeLength^2)) # sin of base angle
108128
else
109-
topRadius = shape.topDiameter/2
110-
diffRadius = baseRadius - topRadius
111-
sin_phi = diffRadius/sqrt(diffRadius^2 + shape.length^2) # sin of base angle
129+
topRadius = T(0.5*shape.topDiameter)
130+
diffRadius = T(baseRadius - topRadius)
131+
sin_phi = T(diffRadius/sqrt(diffRadius^2 + shapeLength^2)) # sin of base angle
112132
end
113133
if shape.axis == 1
114134
value = e_abs[1] / norm(SVector(e_abs[1], e_abs[2], e_abs[3]))
115135
if value >= sin_phi
116136
if rightCone
117-
return SVector(shape.length, 0.0, 0.0) # apex is support point
137+
return SVector(shapeLength, 0.0, 0.0) # apex is support point
118138
else # frustum of a cone
119139
enorm = norm(SVector(e_abs[2], e_abs[3]))
120140
if enorm > Modia3D.neps
121-
return SVector(shape.length, 0.0, 0.0) + SVector(0.0, topRadius*e_abs[2], topRadius*e_abs[3]) / enorm # point on top circle is support point
141+
return SVector(shapeLength, 0.0, 0.0) + SVector(0.0, topRadius*e_abs[2], topRadius*e_abs[3]) / enorm # point on top circle is support point
122142
else
123-
return SVector(shape.length, 0.0, 0.0) # top circle center is support point
143+
return SVector(shapeLength, 0.0, 0.0) # top circle center is support point
124144
end
125145
end
126146
else
127147
enorm = norm(SVector(e_abs[2], e_abs[3]))
128148
if enorm > Modia3D.neps
129149
return SVector(0.0, baseRadius*e_abs[2], baseRadius*e_abs[3]) / enorm # point on base circle is support point
130150
else
131-
return SVector(0.0, 0.0, 0.0) # base circle center is support point
151+
return SVector{3,T}(0.0, 0.0, 0.0) # base circle center is support point
132152
end
133153
end
134154
elseif shape.axis == 2
135155
value = e_abs[2] / norm(SVector(e_abs[1], e_abs[2], e_abs[3]))
136156
if value >= sin_phi
137157
if rightCone
138-
return SVector(0.0, shape.length, 0.0) # apex is support point
158+
return SVector(0.0, shapeLength, 0.0) # apex is support point
139159
else # frustum of a cone
140160
enorm = norm(SVector(e_abs[3], e_abs[1]))
141161
if enorm > Modia3D.neps
142-
return SVector(0.0, shape.length, 0.0) + SVector(topRadius*e_abs[1], 0.0, topRadius*e_abs[3]) / enorm # point on top circle is support point
162+
return SVector(0.0, shapeLength, 0.0) + SVector(topRadius*e_abs[1], 0.0, topRadius*e_abs[3]) / enorm # point on top circle is support point
143163
else
144-
return SVector(0.0, shape.length, 0.0) # top circle center is support point
164+
return SVector(0.0, shapeLength, 0.0) # top circle center is support point
145165
end
146166
end
147167
else
148168
enorm = norm(SVector(e_abs[3], e_abs[1]))
149169
if enorm > Modia3D.neps
150170
return SVector(baseRadius*e_abs[1], 0.0, baseRadius*e_abs[3]) / enorm # point on base circle is support point
151171
else
152-
return SVector(0.0, 0.0, 0.0) # base circle center is support point
172+
return SVector{3,T}(0.0, 0.0, 0.0) # base circle center is support point
153173
end
154174
end
155175
else
156176
value = e_abs[3] / norm(SVector(e_abs[1], e_abs[2], e_abs[3]))
157177
if value >= sin_phi
158178
if rightCone
159-
return SVector(0.0, 0.0, shape.length) # apex is support point
179+
return SVector(0.0, 0.0, shapeLength) # apex is support point
160180
else # frustum of a cone
161181
enorm = norm(SVector(e_abs[1], e_abs[2]))
162182
if enorm > Modia3D.neps
163-
return SVector(0.0, 0.0, shape.length) + SVector(topRadius*e_abs[1], topRadius*e_abs[2], 0.0) / enorm # point on top circle is support point
183+
return SVector(0.0, 0.0, shapeLength) + SVector(topRadius*e_abs[1], topRadius*e_abs[2], 0.0) / enorm # point on top circle is support point
164184
else
165-
return SVector(0.0, 0.0, shape.length) # top circle center is support point
185+
return SVector(0.0, 0.0, shapeLength) # top circle center is support point
166186
end
167187
end
168188
else
169189
enorm = norm(SVector(e_abs[1], e_abs[2]))
170190
if enorm > Modia3D.neps
171191
return SVector(baseRadius*e_abs[1], baseRadius*e_abs[2], 0.0) / enorm # point on base circle is support point
172192
else
173-
return SVector(0.0, 0.0, 0.0) # base circle center is support point
193+
return SVector{3,T}(0.0, 0.0, 0.0) # base circle center is support point
174194
end
175195
end
176196
end
@@ -180,26 +200,29 @@ end
180200
# G. Hippmann: Outer half circles of beam
181201
@inline function supportPoint_abs_Beam(shape::Beam, e_abs::SVector{3,T}) where {T}
182202
@inbounds begin
203+
halfLength = T(0.5*shape.length)
204+
halfWidth = T(0.5*shape.width)
205+
halfThickness = T(0.5*shape.thickness)
183206
if shape.axis == 1
184207
enorm = norm(SVector(e_abs[1], e_abs[2]))
185208
if enorm <= Modia3D.neps
186-
return SVector(Basics.sign_eps(e_abs[1])*shape.length/2, 0.0, Basics.sign_eps(e_abs[3])*shape.thickness/2)
209+
return SVector(Basics.sign_eps(e_abs[1])*halfLength, 0.0, Basics.sign_eps(e_abs[3])*halfThickness)
187210
else
188-
return SVector(Basics.sign_eps(e_abs[1])*shape.length/2, 0.0, Basics.sign_eps(e_abs[3])*shape.thickness/2) + SVector(shape.width/2*e_abs[1], shape.width/2*e_abs[2], 0.0)/enorm
211+
return SVector(Basics.sign_eps(e_abs[1])*halfLength, 0.0, Basics.sign_eps(e_abs[3])*halfThickness) + SVector(halfWidth*e_abs[1], halfWidth*e_abs[2], 0.0)/enorm
189212
end
190213
elseif shape.axis == 2
191214
enorm = norm(SVector(e_abs[2], e_abs[3]))
192215
if enorm <= Modia3D.neps
193-
return SVector(Basics.sign_eps(e_abs[1])*shape.thickness/2, Basics.sign_eps(e_abs[2])*shape.length/2, 0.0)
216+
return SVector(Basics.sign_eps(e_abs[1])*halfThickness, Basics.sign_eps(e_abs[2])*halfLength, 0.0)
194217
else
195-
return SVector(Basics.sign_eps(e_abs[1])*shape.thickness/2, Basics.sign_eps(e_abs[2])*shape.length/2, 0.0) + SVector(0.0, shape.width/2*e_abs[2], shape.width/2*e_abs[3])/enorm
218+
return SVector(Basics.sign_eps(e_abs[1])*halfThickness, Basics.sign_eps(e_abs[2])*halfLength, 0.0) + SVector(0.0, halfWidth*e_abs[2], halfWidth*e_abs[3])/enorm
196219
end
197220
else
198221
enorm = norm(SVector(e_abs[3], e_abs[1]))
199222
if enorm <= Modia3D.neps
200-
return SVector(0.0, Basics.sign_eps(e_abs[2])*shape.thickness/2, Basics.sign_eps(e_abs[3])*shape.length/2)
223+
return SVector(0.0, Basics.sign_eps(e_abs[2])*halfThickness, Basics.sign_eps(e_abs[3])*halfLength)
201224
else
202-
return SVector(0.0, Basics.sign_eps(e_abs[2])*shape.thickness/2, Basics.sign_eps(e_abs[3])*shape.length/2) + SVector(shape.width/2*e_abs[1], 0.0, shape.width/2*e_abs[3])/enorm
225+
return SVector(0.0, Basics.sign_eps(e_abs[2])*halfThickness, Basics.sign_eps(e_abs[3])*halfLength) + SVector(halfWidth*e_abs[1], 0.0, halfWidth*e_abs[3])/enorm
203226
end
204227
end
205228
end
@@ -210,7 +233,7 @@ end
210233
e_absVec = Vector{SVector{3,Float64}}(undef, 1)
211234
e_absVec[1] = e_abs
212235
(max_value, position) = findmax(broadcast(dot, shape.objPoints, e_absVec))
213-
return shape.objPoints[position]
236+
return SVector{3,T}(shape.objPoints[position])
214237
end
215238

216239

0 commit comments

Comments
 (0)