How do I make points inbetween two points as if they were within a circle

Ok so basically what I wanna do is make a bunch of parts which are put together to make a straight line which indicates the route troops will be going on a circular earth map. I think what I wanna do is like generate points in-between those 2 points (the position of the troop and the mouse hit position) as if it were a circle and those generated points would be the line part positions. I think I’ll have to do some math and trigonometry but I suck at that.

Here’s what it could look like.


The curvature of the line would be hard to see from this angle so I made a 2D version of my problem

1 Like

You can use pathfinding service to calculate the path, then loop through all of the waypoints and put a part at the position of that waypoint.

local PathfindingService = game:GetService("PathfindingService")
 
local Point1 = --start position Vector3 value
local Point2 = --end position Vector3 value

path:ComputeAsync(Point1, Point2)

local waypoints = path:GetWaypoints()

for I, waypoint in pairs(waypoints) do
      local part = Instance.new("Part", workspace)
      part.Position = waypoint.Position
     part.Anchored = true
      part.Size = Vector3.new(1,1,1)
end

Hmm here’s a solution using rotation between two vectors

Except modified to use a decimal percentage:

local function AngleBetween(vector1, vector2)
	return math.acos(math.clamp(vector1.Unit:Dot(vector2.Unit), -1, 1))
end

local function rotateVectorAround( v, amount, axis )
	return CFrame.fromAxisAngle(axis, amount):VectorToWorldSpace(v)
end

local function rotateVectorSpherePointsPercentage(point1,point2,centerOfSphere,decimalPercentage)
	local radius1 = point1-centerOfSphere
	local radius2 = point2-centerOfSphere
	local angle = AngleBetween(radius1,radius2)
	local rotationAxis = radius1:Cross(radius2)
	if not (radius1:Dot(radius2) > 0.99999) then -- if there is a rotation
		local radius3 = rotateVectorAround(radius1,angle*decimalPercentage,rotationAxis)
		local pointOnSphere = centerOfSphere+radius3
		return radius3
	end
end

The idea what the rotateVectorSpherePointsPercentage function. By rotating the radius vector of the sphere from point1 to point2.

pointOnSphere

1 Like

Using Path Finding Service seems to be the easiest way to go around this.

No i think pathfinding service is overkill for this + I couldn’t even get it to work

1 Like

Something like this?
image

You can use spherical linear interpolation (slerp) to linearly interpolate along the surface of a sphere.

Here’s an article on it: Slerp - Wikipedia

And here’s the code I used to generate the above image:

local sin, cos, acos = math.sin, math.cos, math.acos

function slerp(p0, p1, t)
	--From https://en.wikipedia.org/wiki/Slerp
	-- See "Geometric Slerp"
	local l = p0.Magnitude
	p0 = p0.Unit
	p1 = p1.Unit
	local Omega = acos(p0:Dot(p1))
	return (
		p0 * sin( (1 - t) * Omega) / sin(Omega) +
		p1 * sin( (t    ) * Omega) / sin(Omega)
	) * l
end

local steps = 10
local A, B, C = game.Workspace.A, game.Workspace.B, game.Workspace.C
local last_p = A.Position
for i = 1/steps, 1, 1/steps do
	local c = C:Clone()
	local p = slerp(A.Position, B.Position, i)
	local d = (p - last_p).Magnitude
	c.Size = Vector3.new(1, 1, d)
	c.CFrame = CFrame.new(p, last_p) * CFrame.new(0, 0, -d * 0.5)
	c.Parent = game.Workspace
	last_p = p
end
C:Destroy()

And here’s an example place file:

Slerp.rbxl (21.8 KB)

The slerp function assumes the center of the sphere is (0, 0, 0) and that p0 is on the surface of the sphere. p1 doesn’t have to be on the surface, but it does have to be different from (0, 0, 0). The returned point is along the surface of the sphere from p0 to p1, acting as if p1 were on the surface of the sphere.

3 Likes

Wow that actually works pretty well, thanks!

The only downside is that I don’t understand it and whenever I try to put code in my game I try to know what it does, how do you even come up with this kind of stuff?

1 Like

Well I’d heard of “slerp” before and I think I did some spherical geometry for a high school project, but other than that it’s mostly just having strong google-fu