Rail3D*


 

Auto Level- Crossing



My reasoning for creating this script was that I find creating levels crossings a bit tedious to create - there are lots of steps to be performed and if you don’t get them right it does not work properly. At the moment I can’t achieve full automation but the beginnings are there…

This first experimental script creates a crossing on a single track line, where the road crosses at exactly 90º to the railway.

First of all setup the variables:

Init()
{
	debug.printL("Level Crossing");

	node mNode=Document.GetCurrentNode();

	float x1=mNode.GetX();
	float y1=mNode.GetY();
	float z=mNode.GetZ();
	float theta=mNode.GetAlpha();

	float lclen=15.0;

	float radians=3.1417/180; //ta mh!

We need the (x,y,z) coordinate of the node of the initial node (the current end of the railway), and the direction (angle).

@lclen@ is the length the track will be extended as part of the level crossing. I’ve also got a static radians conversion as rail3d uses radians. This will come in handy later.

Next, I must calculate the position of the next node of the railway:

//calc x, cos angle = adj/hyp

	debug.printL("Trig Time");

	float x2=lclen*sin(theta);
	x2=x2+x1;

	debug.printL(x2);

	float y2=lclen*cos(theta);
	y2=y2+y1;

	debug.printL(y2);

	Document.BuildLink(x1,y1,z,x2,y2,z);

Note that z is the same for both nodes as a level crossing is by nature level.

Next I must calculate what angle 90º will be in the context of the railway. I could take an input here, which is why I have specified @roaddeg@ as roaddeg not nintydeg. The script is designed to allow for variable angle crossings at a later date.

90º is converted to radians.

We now need to involve theta:

The angle of the road from vertical is calculated by pi - (pi/2 - theta).

Edit- I believe my logic to be 180 - (90 - theta) which produces the large angle required from the vertical

//90 deg for starters

	float roaddeg=90.0;

	float roadrad=roaddeg*radians;

	float invroadrad=3.1417-(roadrad-theta);
	if(invroadrad < 0)
	{
	invroadrad = invroadrad * -1;
	}

An if block is used to compensate for problems that would occur if we gave the script a variable angle to deal with.

Now I’ve got the angle of the between the road and railway, I can start to build the road links:

//length of lc is 15m, each road = 4m wide, thus intersection of road is 5.5m from
//original node

	float roadisec=5.5;


	debug.printL("Trig Time - find 1st road intersection");

	float xa=roadisec*sin(theta);
	xa=xa+x1;

	debug.printL(xa);

	float ya=roadisec*cos(theta);
	ya=ya+y1;

	debug.printL(ya);

	debug.printL("Road start");

	float roadlen=10.0;

	float xb=roadlen*sin(invroadrad);
	float yb=roadlen*cos(invroadrad);
	float rx1=xa-xb;
	float ry1=ya-yb;

	float rx2=xb+xa;
	float ry2=yb+ya;

	Document.SetTrackType("Road");
	Document.SetLineSpacing()=4.0;

	Document.BuildLink(rx1,ry1,z,rx2,ry2,z);
}

In the above I calculate or define:

  1. the position of the intersection between road and railway (this is 5.5m into the 15m stretch of railway)
  2. create a “logical” node at the intersection
  3. from this logical node, I calculate the position of the nodes at either end of the strip of road, using a road length of 10m

Note again z is static.

What happens next?

I need to set the track spacing of the road to 4.0m and create another link adjacent to the road, as roads are usually “two track”.

I would also need to set the cutting widths of all the links I have created above.

Lastly, the actual level crossing gates need to be fixed to the appropriate node.

I would ideally like to further this script so that one can click a node, then click Run Script -→ Create lc and no user intervention is required, aside perhaps the input of a value of the angle of intersection.

Alan Perryman, January 2007



import