How to make multiple attachments align in a curve between 2 points

Hello!
I am working on a train system and I am at a point where I am working on the gangway of the train and one thing I am thinking is aligning 12 attachments between 2 points.

Here is a photo.
I want to make it so that 12 attachments align perfectly in a curved sort of way when the train turns.
The attachments should spread out evenly both on the X and Z axis.


Here is one of my code attempts but didn’t work properly.

local Gangway = script.Parent

local Attachment1 = Gangway.Parent.PowerCar.Train.BackWall.GW
local Attachment2 = Gangway.Parent.TrailerCar.Train.BackWall.GW

local X1 = Attachment1.WorldPosition.X
local X2 = Attachment2.WorldPosition.X

local FrontZ = Attachment1.WorldPosition.Z
local RearZ = Attachment2.WorldPosition.Z

local DistanceX = (X1 - X2) / 11
local DistanceZ = (FrontZ - RearZ) / 11
		
for Number = 1, 12 do
	local Attachment = Gangway[Number]
			
	local X = (DistanceX * (Number - 1))
	local Z = (Gangway.Size.Z / 2) - (DistanceZ * (Number - 1))
	Attachment.Position = Vector3.new(X, 0, Z)
end

Points A and B are placed inside of the end wall of each carriage and are used as the reference to figure out the distance between each point.

FYI for those wondering how this would be useful for a gangway, I’ll have to reupload the gangway as one whole mesh with bones in it (Still need to learn how to do this) and then while the train is moving it will adjust the bones but I am using attachments right now as they are close to the same as bones so I can experiment with this.

Thanks.

Maybe try using constraints to join them together?

Join the carriages together?

The gangway is a flexible piece of the train which people use to walk through to get between 2 carriages.

The gangway mesh I will be using will have bones (pretty much the same as in attachment) but I am using attachments as in experiment.

This will probably require some sort of math.pi sort of stuff that I don’t know about.

If it has bones then pretty sure you could use a rigid body constraint to connect them together

The gangway bends so I need it to move around and the bones to move when the train turns corners, not to be fixed in place.

Look at some other constraints then. but just try it out

I have thought of an idea that ‘could’ work.

I’ll get back to you soon.

1 Like

Never mind, I was working on some silly math formula but I don’t think it was right.

I think it would be something similar to “Quad Curve” but I don’t know how I’d get the control point.
image

1 Like

im pretty sure the control points are something you define yourself

Yeah, I think so too but I want to make it so the game would figure it out itself because the position will change depending on how far it’s turned.

You can possibly get the Control Point by using the same methods as in this topic.

Though this might be over-complicated to just get a curve.

Looks promising but, I’ll probably have to spend a few days working on this. I’m about to go to sleep now so people may have other solutions that are easier.

This is something I just asked chatGBT
To find the control point (also known as a Bezier control point) between two points, you need to specify how you want to create the curve between those points. In most cases, you’ll be working with quadratic or cubic Bezier curves. Here’s how to find the control point for both cases:

  1. Quadratic Bezier Curve:

    • Given two points: P0 (start point) and P2 (end point), and you want to find the control point P1.
    • Calculate P1 as follows:
      P1 = (P0 + P2) / 2
    • P1 will be the midpoint between P0 and P2.
  2. Cubic Bezier Curve:

    • Given two points: P0 (start point) and P3 (end point), and you want to find the control points P1 and P2.
    • Choose two other points P0’ and P3’ that are close to P0 and P3, respectively.
    • Calculate P1 and P2 as follows:
      P1 = P0 + (P0’ - P0) / 3
      P2 = P3 + (P3’ - P3) / 3
    • P1 and P2 should be placed one-third and two-thirds of the way between P0 and P3, respectively.

The choice of P0’ and P3’ can depend on your specific requirements, but typically they are chosen to create a smooth curve. You may experiment with different values to achieve the desired curve shape.

Keep in mind that the control points determine the shape of the Bezier curve, so the placement of P1 and P2 will affect the curve’s behavior between P0 and P3.

Does anyone have any other solutions I can try?
I can’t seem to get it to work.

Get the center of position between both positions, 2 Vector3s so that’s easy:

local center = (position1 + position2) / 2

Pretty simple, then you would need to push this point on X/Z axis depending on the movement of the train, say you have the direction in which the train is turning as a vector3, we can do this:

local offset = turnDirection.Unit * curvature

And the final position of the center point is just

center + offset

For the side that’s closer to the center of rotation you will use -offset as it needs to go inwards and not outwards. I came up with the math right now so it may or may not work lol, it theoretically should though… After u have this “center” point you should be able to move the mesh, you said you had bones so afaik it’s easy to do it with that, I’ve never worked with bones though.


I didn’t tell you how to calculate curvature so I’ll guess you don’t know and tell you, in case you already knew u can ignore this part.
We first need start and end of the curve, Y-axis is ignored as we don’t need that, the train won’t drive upwards or downwards, will it?

local curveStart = Vector3.new(x1, 0, z1)
local curveEnd = Vector3.new(x2, 0, z2)

We need to calculate the slop, m, now, it’s the same as 2D graphs, our 2D plain is X and Z (X and Y in normal 2D) so it’s pretty easy, instead of doing (y2 - y1) / (x2 - x1) we will do (z2 - z1) / (x2 - x1)

local m = (curveEnd.Z - curveStart.Z) / (curveEnd.X - curveStart.Y)

We now need to calculate the perpendicular bisector, it’s pretty easy. Perpendicular bisector is the line that intersects the original line at a right angle and passes through the midpoint of the line segment between the two points.

local midpoint = (curveStart + curveEnd) / 2
local perpendicularSlope = -1 / m
local perpendicularBisector = midpoint.Z - perpendicularSlope * midpoint.X

Now we calculate the center of curvature on each of our axes.

local centerOfCurvatureX = (midpoint.Z - perpendicularBisector) / (2 * perpendicularSlope)
local centerOfCurvatureZ = perpendicularSlope * centerOfCurvatureX + perpendicularBisector

And now the the radius of curvature (distance from the curveStart to the center of curvature).

local radiusOfCurvature = math.sqrt((curveStart.X - centerOfCurvatureX) ^ 2 + (curveStart.Z - centerOfCurvatureZ) ^ 2)

And last but not least we calculate the actual curvature

local curvature = 1 / radiusOfCurvature

Full code:

local curveStart = Vector3.new(x1, 0, z1)
local curveEnd = Vector3.new(x2, 0, z2)

local m = (curveEnd.Z - curveStart.Z) / (curveEnd.X - curveStart.X)

local midpoint = (curveStart + curveEnd) / 2
local perpendicularSlope = -1 / m
local perpendicularIntercept = midpoint.Z - perpendicularSlope * midpoint.X

local centerOfCurvatureX = (midpoint.Z - perpendicularIntercept) / (2 * perpendicularSlope)
local centerOfCurvatureZ = perpendicularSlope * centerOfCurvatureX + perpendicularIntercept

local radiusOfCurvature = math.sqrt((curveStart.X - centerOfCurvatureX) ^ 2 + (curveStart.Z - centerOfCurvatureZ) ^ 2)

local curvature = 1 / radiusOfCurvature

Too long? I’m just as surprised as you are! Lmao

Uhm, my eyes hurt from this… I’m not too good at math (not this sort of stuff at least). Could I give you like a model of the thing and get you to do it for me? lol (Not being lazy… well, maybe I am but this is too much for me lol)

Lmao, can’t blame you. As I mentioned before I haven’t worked with bones so I don’t know how to make them bend or all of that. Just copy the last code at the end and read the start and you should be good to go.

Lol.

I haven’t worked with bones either so its something I’ll have to learn and this might not even work for it but I think it might but I think bones are just the exact same as attachments (which I’m using as a test) but maybe with some changes.

Ok, I’ll try lol

Wait, how exactly do I position all 12 attachments on each side?

U can use lerping between center and start for 6 then center and end for the other 6

Lol, I’ll come back tomorrow or something because I’m too tired for this now lol (Its 9PM for me so that’s why).

Aha, it’s 11:30 am for me so that’s a really lovely time zone difference lmao. Good luck.