How do I clamp a 3d rotation (a vector) within a cone about a (second) vector?
Vector within a cone of another vector? I believe I’ve done something similar with my CCDIK module here is how it went by measuring the angles for a ball socket constraint. Is this what you were looking for?
local centerAxis = axisAttachment.WorldAxis local currentCenterAxis = jointAttachment.WorldAxis local angleDifference = VectorUtil.AngleBetween(currentCenterAxis,centerAxis) local constraintUpperAngle = math.rad(jointConstraintInfo.UpperAngle) or math.rad(45) --out of bounds constrain it to world axis of the socket if angleDifference > constraintUpperAngle then local axis = currentCenterAxis:Cross(centerAxis) local angleDifference = angleDifference-constraintUpperAngle local newCenterAxisWithinBounds = rotateVectorAround( currentCenterAxis, angleDifference, axis ) self.rotateJointFromTo(motor6d,currentCenterAxis,newCenterAxisWithinBounds,part0CF.RightVector) end
Rotating vectors is like doing spherical linear interpolation (slerp) of the endpoints of the vectors. We’ll need to compute the angle between the vectors:
function angleBetweenVectors(p0, p1) return local angle = math.acos( p0.Unit:Dot(p1.Unit) ) --Angle between the vectors (O to p0) and (O to p1) end
Here’s the slerp function
function slerp(p0, p1, t) local angle = angleBetweenVectors(p0, p1) local sinOfAngle = math.sin(angle) return p0 * sin((1-t) * angle) / sinOfAngle + p1 * sin(t * angle) / sinOfAngle end
And here’s a function that, given a vector and a cone, returns the vector but clamped inside the cone.
function constrainVectorInsideCone(toConstrain, coneDirection, coneAngle) local currentAngle = angleBetweenVectors(toConstrain, coneCenter) if currentAngle > coneAngle then --If not already inside cone local angleProportionToEdgeOfCone = coneAngle / currentAngle coneDirection = coneDirection.Unit * toConstraint.Magnitude --Clamping shouldn't change the length of the vector, so slerp from a cone direction that has the same length as the original vector toConstrain = slerp(coneDirection, toConstrain, angleProportionToEdgeOfCone) end return toConstrain end
Hope this helps, let me know if it doesn’t work as expected or if you have questions
@ThanksRoBama worked exactly as expected, ty.
@dthecoolest, is rotateVectorAround a means to hinge around a cross product between two vectors in your module? This CCDIK looks very nice and I would tip you a coffee for it if you have patreon.
I will additionally be trying out specifying an x and y dim angle to constrain a vector to an oval cone.