@@ -120,90 +120,94 @@ end
120120# for frustum of a cone: A. Neumayr, G. Hippmann
121121@inline function supportPoint_abs_Cone (shape:: Cone , e_abs:: SVector{3,T} , collisionSmoothingRadius:: T ) where {T}
122122 @inbounds begin
123+ baseRadius = T (0.5 * shape. diameter)
124+ shapeLength = T (shape. length)
123125 rightCone = T (shape. topDiameter) == T (0.0 )
124- R = T (0.5 * shape. diameter)
125- H = T (shape. length)
126- r = collisionSmoothingRadius
127-
128- Rright = (R* H- R* r- r* sqrt (H^ 2 + R^ 2 ))/ H
129- Hright = Rright/ (R/ H)
130-
131126 if rightCone
132- baseRadius = Rright
133- shapeLength = Hright
134- sin_phi = T (baseRadius/ sqrt (baseRadius^ 2 + shapeLength^ 2 )) # sin of base angle
127+ slantHeight = T (sqrt (baseRadius^ 2 + shapeLength^ 2 ))
128+ sin_phi = T (baseRadius/ slantHeight) # sin of base angle
135129 else
136- Rt = T (0.5 * shape. topDiameter)
137- Hcone = H - 2 * r
138- diffRadius = R - Rt
139- Rcone = diffRadius* Hcone/ H
140- topRadius = Rt - Rright + Rcone
141- @assert (topRadius > 0.0 )
142- shapeLength = Hcone
143- baseRadius = topRadius + Rcone
144- sin_phi = T (Rcone/ sqrt (Rcone^ 2 + shapeLength^ 2 )) # sin of base angle
130+ topRadius = T (0.5 * shape. topDiameter)
131+ diffRadius = T (baseRadius - topRadius)
132+ slantHeight = T (sqrt (diffRadius^ 2 + shapeLength^ 2 ))
133+ sin_phi = T (diffRadius/ slantHeight) # sin of base angle
145134 end
146135 if shape. axis == 1
147136 value = e_abs[1 ] / norm (SVector (e_abs[1 ], e_abs[2 ], e_abs[3 ]))
148137 if value >= sin_phi
149138 if rightCone
150- return SVector (shapeLength, 0.0 , 0.0 ) # apex is support point
139+ hPos = T (shapeLength - collisionSmoothingRadius* slantHeight/ baseRadius) # shapeLength - r/sin(phi)
140+ return SVector (hPos, 0.0 , 0.0 ) # apex is support point
151141 else # frustum of a cone
142+ hPos = T (shapeLength - collisionSmoothingRadius)
152143 enorm = norm (SVector (e_abs[2 ], e_abs[3 ]))
153144 if enorm > Modia3D. nepsType (T)
154- 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
145+ topRadius = T (topRadius - collisionSmoothingRadius* (slantHeight - baseRadius)/ shapeLength) # topRadius - r*(1/cos(phi) - tan(phi))
146+ return SVector (hPos, 0.0 , 0.0 ) + SVector (0.0 , topRadius* e_abs[2 ], topRadius* e_abs[3 ]) / enorm # point on top circle is support point
155147 else
156- return SVector (shapeLength , 0.0 , 0.0 ) # top circle center is support point
148+ return SVector (hPos , 0.0 , 0.0 ) # top circle center is support point
157149 end
158150 end
159151 else
152+ hPos = collisionSmoothingRadius
160153 enorm = norm (SVector (e_abs[2 ], e_abs[3 ]))
161154 if enorm > Modia3D. nepsType (T)
162- return SVector (0.0 , baseRadius* e_abs[2 ], baseRadius* e_abs[3 ]) / enorm # point on base circle is support point
155+ baseRadius = T (baseRadius - collisionSmoothingRadius* (slantHeight + baseRadius)/ shapeLength) # topRadius - r*(1/cos(phi) + tan(phi))
156+ return SVector (hPos, baseRadius* e_abs[2 ], baseRadius* e_abs[3 ]) / enorm # point on base circle is support point
163157 else
164- return SVector {3,T} (0.0 , 0.0 , 0.0 ) # base circle center is support point
158+ return SVector {3,T} (hPos , 0.0 , 0.0 ) # base circle center is support point
165159 end
166160 end
167161 elseif shape. axis == 2
168162 value = e_abs[2 ] / norm (SVector (e_abs[1 ], e_abs[2 ], e_abs[3 ]))
169163 if value >= sin_phi
170164 if rightCone
171- return SVector (0.0 , shapeLength, 0.0 ) # apex is support point
165+ hPos = T (shapeLength - collisionSmoothingRadius* slantHeight/ baseRadius) # shapeLength - r/sin(phi)
166+ return SVector (0.0 , hPos, 0.0 ) # apex is support point
172167 else # frustum of a cone
168+ hPos = T (shapeLength - collisionSmoothingRadius)
173169 enorm = norm (SVector (e_abs[3 ], e_abs[1 ]))
174170 if enorm > Modia3D. nepsType (T)
175- 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
171+ topRadius = T (topRadius - collisionSmoothingRadius* (slantHeight - baseRadius)/ shapeLength) # topRadius - r*(1/cos(phi) - tan(phi))
172+ return SVector (0.0 , hPos, 0.0 ) + SVector (topRadius* e_abs[1 ], 0.0 , topRadius* e_abs[3 ]) / enorm # point on top circle is support point
176173 else
177- return SVector (0.0 , shapeLength , 0.0 ) # top circle center is support point
174+ return SVector (0.0 , hPos , 0.0 ) # top circle center is support point
178175 end
179176 end
180177 else
178+ hPos = collisionSmoothingRadius
181179 enorm = norm (SVector (e_abs[3 ], e_abs[1 ]))
182180 if enorm > Modia3D. nepsType (T)
183- return SVector (baseRadius* e_abs[1 ], 0.0 , baseRadius* e_abs[3 ]) / enorm # point on base circle is support point
181+ baseRadius = T (baseRadius - collisionSmoothingRadius* (slantHeight + baseRadius)/ shapeLength) # topRadius - r*(1/cos(phi) + tan(phi))
182+ return SVector (baseRadius* e_abs[1 ], hPos, baseRadius* e_abs[3 ]) / enorm # point on base circle is support point
184183 else
185- return SVector {3,T} (0.0 , 0.0 , 0.0 ) # base circle center is support point
184+ return SVector {3,T} (0.0 , hPos , 0.0 ) # base circle center is support point
186185 end
187186 end
188187 else
189188 value = e_abs[3 ] / norm (SVector (e_abs[1 ], e_abs[2 ], e_abs[3 ]))
190189 if value >= sin_phi
191190 if rightCone
192- return SVector (0.0 , 0.0 , shapeLength) # apex is support point
191+ hPos = T (shapeLength - collisionSmoothingRadius* slantHeight/ baseRadius) # shapeLength - r/sin(phi)
192+ return SVector (0.0 , 0.0 , hPos) # apex is support point
193193 else # frustum of a cone
194+ hPos = T (shapeLength - collisionSmoothingRadius)
194195 enorm = norm (SVector (e_abs[1 ], e_abs[2 ]))
195196 if enorm > Modia3D. nepsType (T)
196- 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
197+ topRadius = T (topRadius - collisionSmoothingRadius* (slantHeight - baseRadius)/ shapeLength) # topRadius - r*(1/cos(phi) - tan(phi))
198+ return SVector (0.0 , 0.0 , hPos) + SVector (topRadius* e_abs[1 ], topRadius* e_abs[2 ], 0.0 ) / enorm # point on top circle is support point
197199 else
198- return SVector (0.0 , 0.0 , shapeLength ) # top circle center is support point
200+ return SVector (0.0 , 0.0 , hPos ) # top circle center is support point
199201 end
200202 end
201203 else
204+ hPos = collisionSmoothingRadius
202205 enorm = norm (SVector (e_abs[1 ], e_abs[2 ]))
203206 if enorm > Modia3D. nepsType (T)
204- return SVector (baseRadius* e_abs[1 ], baseRadius* e_abs[2 ], 0.0 ) / enorm # point on base circle is support point
207+ baseRadius = T (baseRadius - collisionSmoothingRadius* (slantHeight + baseRadius)/ shapeLength) # topRadius - r*(1/cos(phi) + tan(phi))
208+ return SVector (baseRadius* e_abs[1 ], baseRadius* e_abs[2 ], hPos) / enorm # point on base circle is support point
205209 else
206- return SVector {3,T} (0.0 , 0.0 , 0.0 ) # base circle center is support point
210+ return SVector {3,T} (0.0 , 0.0 , hPos ) # base circle center is support point
207211 end
208212 end
209213 end
0 commit comments