@@ -120,90 +120,94 @@ end
120
120
# for frustum of a cone: A. Neumayr, G. Hippmann
121
121
@inline function supportPoint_abs_Cone (shape:: Cone , e_abs:: SVector{3,T} , collisionSmoothingRadius:: T ) where {T}
122
122
@inbounds begin
123
+ baseRadius = T (0.5 * shape. diameter)
124
+ shapeLength = T (shape. length)
123
125
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
-
131
126
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
135
129
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
145
134
end
146
135
if shape. axis == 1
147
136
value = e_abs[1 ] / norm (SVector (e_abs[1 ], e_abs[2 ], e_abs[3 ]))
148
137
if value >= sin_phi
149
138
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
151
141
else # frustum of a cone
142
+ hPos = T (shapeLength - collisionSmoothingRadius)
152
143
enorm = norm (SVector (e_abs[2 ], e_abs[3 ]))
153
144
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
155
147
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
157
149
end
158
150
end
159
151
else
152
+ hPos = collisionSmoothingRadius
160
153
enorm = norm (SVector (e_abs[2 ], e_abs[3 ]))
161
154
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
163
157
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
165
159
end
166
160
end
167
161
elseif shape. axis == 2
168
162
value = e_abs[2 ] / norm (SVector (e_abs[1 ], e_abs[2 ], e_abs[3 ]))
169
163
if value >= sin_phi
170
164
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
172
167
else # frustum of a cone
168
+ hPos = T (shapeLength - collisionSmoothingRadius)
173
169
enorm = norm (SVector (e_abs[3 ], e_abs[1 ]))
174
170
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
176
173
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
178
175
end
179
176
end
180
177
else
178
+ hPos = collisionSmoothingRadius
181
179
enorm = norm (SVector (e_abs[3 ], e_abs[1 ]))
182
180
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
184
183
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
186
185
end
187
186
end
188
187
else
189
188
value = e_abs[3 ] / norm (SVector (e_abs[1 ], e_abs[2 ], e_abs[3 ]))
190
189
if value >= sin_phi
191
190
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
193
193
else # frustum of a cone
194
+ hPos = T (shapeLength - collisionSmoothingRadius)
194
195
enorm = norm (SVector (e_abs[1 ], e_abs[2 ]))
195
196
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
197
199
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
199
201
end
200
202
end
201
203
else
204
+ hPos = collisionSmoothingRadius
202
205
enorm = norm (SVector (e_abs[1 ], e_abs[2 ]))
203
206
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
205
209
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
207
211
end
208
212
end
209
213
end
0 commit comments