Train Car Problems

BlitzMax Forums/BlitzMax Programming/Train Car Problems

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()