Rail3D*


 

Arcs And Circles



This script allows you to build arcs and circles of any radius and angle. Because Rail3D actually generates Bezier curves, which only approximate to arcs over a small angle, the script lets you divide the curve up into an arbitrary number of sections. Typically you should use at least eight sections for a complete circle.


50m radius, −270 degrees, nine segments

The script starts out from the current node mNde, works out where the centre of the circle should be, and creates the new nodes and links using standard trig functions.

Complete script

If you want to try this script, just copy it into a text file and save it as arc_script.cpp in your Rail3D/scripts folder. Select a node in your layout as starting point, then run the script from the Tools menu.

// Script to create a series of arc segments
// Mark Hodson 31.01.2007 for  Rail3D.2kd 101.1

Init()
{
	node mNde=Document.GetCurrentNode();
	node mNde1=mNde.GetConnectedNode(0,0);
	node mNde2=mNde.GetConnectedNode(1,0);
	node mNde3;	//temporary node

	float radians=3.1417/180;
	float R=InputFloat("Radius in metres");   //Radius in metres


	int nsteps=InputInt("No. of steps");	//number of segments to make 
	float totAngle=InputFloat("Total angle in degrees (+ for left, - for right)");

        //the variable "sign" is set to -1 if the curve is to the right

	float sign=1;

	if(0.0>totAngle)
	{
		sign=-1;
		totAngle=sign*totAngle;
	}


	float AngStep=totAngle/nsteps; //degrees per track section

        //Get the coordinates of the start node
	float x=mNde.GetX();
	float y=mNde.GetY();
	float z=mNde.GetZ();
	float alpha=mNde.GetAlpha();



	//find centre of circle
	float x0=x-(sign*R*cos(alpha));
	float y0=y+(sign*R*sin(alpha));


        //check if the node is connected on both sides

	float xb=mNde2.GetX();

	if(xb==0)	// Which way to go?
	{
		//debug.printL("Inverse");
		alpha=3.1417+alpha;
	}


	int a=1;   //counter for steps
        //coordinates of working points
	float x1;  
	float y1;

	float x2=x;
	float y2=y;

	float theta;

        //repeat for each segment
	while(a<(nsteps+1))
	{
		theta=alpha+(sign*(90-(a*AngStep))*radians);
		x1=R*sin(theta)+x0;
		y1=R*cos(theta)+y0;


		Document.BuildLink(x2,y2,z,x1,y1,z);
		mNde3=Document.GetNode(x1,y1);
		mNde3.SetAlpha((-90*sign*radians)+theta);		

		x2=x1;
		y2=y1;

		a++;
	}


}



import