I have an origin position and an end position which are used for bullets within my game. I would like to calculate the curve direction of the bullet using these two positional values.
To better help you understand what I would like to achieve, I have attached two reference images which I would like to achieve. These positions are three dimensional positions in the world space.
What solutions have you tried so far?
I have tried a few solutions to this problem but most of them end up being inaccurate based on the orientation of the origin. I am not very good at the mathematical side of things.
Well there’s a few ways you could do this. You could add an initial velocity to the right/left side, then add an acceleration/force to change the velocity of the bullet as it travels toward the goal position. You would have to use your physics kinematic equations to make it simple.
You could also make an orbital circular path using a starting point, ending point, and a pivotal center. I recently answered something similar to this, you can check it out here:
I don’t think you really understood the topic correctly. I appreciate your response, however the bullet is not a moving projectile and begins at the origin and ends at the destination.
What I want to accomplish is to create a function which will detect which way a bullet will curve based on the Origin and Destination of the bullet with a response of either ‘Left’ or ‘Right’.
I am not looking to modify the bullet at all, just detect the curvature. Would you happen to know how I could accomplish this?
You could use trigonometry to solve for the angle created between the bullet beam and the triangle formed by the lengths between the horizontal and vertical distances between both points.
Or… you could force a specific orientation to where the origin is always on the bottom (always aligned to one specific axis) and then compare the positions of both points. There are multiple ways to attack this problem, really.
Think of this as a problem where you’re figuring out the angle between the look vector of the origin, and the vector from the origin to the destination point.
In our model, O is the origin and D is the destination. We can calculate the angle theta, which is the angle between the look vector and the vector from O to D by calculating a plane P which both points lie in.
Since for this problem we need a normal vector that stays the same regardless of world orientation, let’s use the y axis as the normal vector N.
local function isDestinationLeftOrRight(origin: Vector3, originLook: Vector3, destination: Vector3): string
-- let's make sure our originLook is a unit vector
originLook = originLook.Unit
local n = Vector3.yAxis -- let's make it the y axis for this problem
local m = (destination - origin).Unit
local s = originLook:Cross(n).Unit
local proj_l_m = m:Dot(originLook)
local proj_s_m = m:Dot(s)
local theta = math.atan2(-proj_s_m, proj_l_m)
return (theta < 0 and "Right") or (theta > 0 and "Left") or "Straight"
end
print(isDestinationLeftOrRight(
workspace.Origin.CFrame.Position,
workspace.Origin.CFrame.LookVector,
workspace.Destination.CFrame.Position
))
This solution works, however, there’s a surprisingly easy way to do this without using trig.
The solution uses the assumption that the right vector of the origin is always going to point away from the left side, thus the dot product will always be negative on the left, and positive on the right. A dot product of 0 is perfectly perpendicular to the right vector, so the direction is straight:
local function getDirection(origin: CFrame, destination: Vector3)
local travel = destination - origin
local dot = origin.RightVector:Dot(travel)
if dot < 0 then
return "Left"
elseif dot > 0 then
return "Right"
else
return "Straight"
end
end
Alternative compact function:
local function getDirection(origin: CFrame, destination: Vector3)
local dot = origin.RightVector:Dot(destination - origin)
return dot < 0 and "Left" or dot > 0 and "Right" or "Straight"
end
Nice! I didn’t even think about this approach, it’s a lot faster.
Now that I think about it, you could also look at the cross product of the look vector and the vector from origin to destination. Then check the sign of the Y component of the resulting vector.