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