Train Car Problems

BlitzMax Forums/BlitzMax Programming/Train Car Problems

I would like to make a train in my game that the player can controll. It is not like a normal train that rides on rails, thie would be simular to a child's pull train that just rolls along the ground. My problem is making and controlling the cars they need to stop when their corners touch and also they need to maintain a set distance from each other at all times. It would be simular to a chain except the links are always a set distance apart.

Here are the specs:
Each car measures 16x24 pixels. The space between the ends of the cars is 4 pixels. Cars need to never intersect, even when the train changes direction. If you can maybe help me I would be really gratefull. I doubt that I can solve this on my own. I do have a function to draw the rotated rectangles, you only need to help me find the midpoints of each car....
Here is a pic to help with the concept:


Tips:

1) keep track of each traincars position from the center of the front of the traincar, not the center of the traincar.

2) work your way down the traincars from the first one, repositioning each, and then fixing it if their corners intersect

3) the corner intersection can be checked by comparing the rotation of two traincars, rather than using any collision detection.

This is a "chain of dots" approach:
NodeDist controls the length of a car (including the distance between the cars) and NodeDist2 is the minimal distance between the startpoint of one car and the endpoint of the next car (indirectly the minimal angle between two cars).

-- Byteemoz

Edit: Changed the example to use float instead of integer math.
SuperStrict
Graphics 800, 600

Local NodeCount:Int = 10
Local NodeDist:Float = 28
Local NodeDist2:Float = 50 ' must be less than 2 * NodeDist

Local NodeX:Float[] = New Float[NodeCount]
Local NodeY:Float[] = New Float[NodeCount]

For Local a:Int = 0 Until NodeCount
	NodeX[a] = 400 - a * NodeDist
	NodeY[a] = 300
Next

Repeat
	
	Cls
	For Local a:Int = 1 Until NodeCount ' draw lines

		DrawLine NodeX[a], NodeY[a], NodeX[a - 1], NodeY[a - 1]
	Next
	For Local a:Int = 0 Until NodeCount ' draw dots
		DrawRect NodeX[a] - 2, NodeY[a] - 2, 5, 5
	Next
	Flip
		
	If NodeX[0] <> MouseX() Or NodeY[0] <> MouseY() Then
		NodeX[0] = MouseX()
		NodeY[0] = MouseY()
		
		For Local n:Int = 0 To 3
			For Local a:Int = 1 Until NodeCount
				Local dist:Float = Sqr( (NodeX[a - 1] - NodeX[a]) ^ 2 + (NodeY[a - 1] - NodeY[a]) ^ 2)
				Local angle:Float = ATan2(NodeY[a] - NodeY[a - 1], NodeX[a - 1] - NodeX[a])
				If Abs(dist - NodeDist) > 2 Then
					NodeX[a] = NodeX[a - 1] - Cos(angle) * NodeDist
					NodeY[a] = NodeY[a - 1] + Sin(angle) * NodeDist
				EndIf
			Next
			For Local a:Int = 2 Until NodeCount
				Local dist:Float = Sqr( (NodeX[a - 2] - NodeX[a]) ^ 2 + (NodeY[a - 2] - NodeY[a]) ^ 2)
				Local angle:Float = ATan2(NodeY[a] - NodeY[a - 2], NodeX[a - 2] - NodeX[a])
				If dist - NodeDist2 < 2 Then
					NodeX[a] = NodeX[a - 2] - Cos(angle) * NodeDist2
					NodeY[a] = NodeY[a - 2] + Sin(angle) * NodeDist2
				EndIf
			Next
		Next
	EndIf
Until KeyHit(KEY_ESCAPE) Or AppTerminate()


Wow that's amazing stuff! Thanks.

Have a question:

Why do you loop it 4 times? (the n loop).

Is it for precision, if i looped 20 times would it be more precise?

also, you can put the lines with the angle calculation in the following IF because you dont need the angle unless the IF conditions are met

Yep I get it. How did you learn this or did you just invent the solution here?

Why do you loop it 4 times? (the n loop).
Is it for precision, if i looped 20 times would it be more precise?
In every loop we gain precision by correnting the distance and angle between the dots and we lose precision by using computer math. So after a certain point (I'm not sure how many loops exactly) we will actually lose precision...

you can put the lines with the angle calculation in the following IF because you dont need the angle unless the IF conditions are met
I hacked this together in a few minutes - it's 100% unoptimised. ;-)

Yep I get it. How did you learn this or did you just invent the solution here?
It's an algorithm to model strings in physical simulations. I think I got it from here...
-- Byteemoz

PS: I changed the example to use float instead of integer math.