Code translation from RhinoScript to DesignScript

Hello everyone,

I am trying to translate the following code written in Rhinoscript to a single code block using DesignScript.

Option Explicit

Dim v
For v = 0 To Pi Step .01
    SPHERE()
Next

Sub SPHERE() 
    Dim u
    Dim x, y, z
    Dim arrPoints
    For u = 0 To 2 * Pi Step .01
        x = 2 + sin(v) * cos(u)
        y = 2 * sin(v) * sin(u)
        z = cos(v)
        If IsArray(arrPoints) Then
            ReDim Preserve arrPoints ( UBound(arrPoints) +1)
        Else
            ReDim arrPoints(0)
        End If
        arrPoints(Ubound(arrPoints)) = Array(x, y, z)
    Next
    Rhino.AddCurve arrPoints
End Sub

Any help to translate the code is greatly appreciated!

At the moment, I am having issues with the for loop in the SPHERE() function definition. My attempt below

geometry = [Imperative]
{
	u = 0.00;
	v = 0.00;
	x = 0.00;
	y = 0.00;
	z = 0.00;
	arrPoints = {};

	for (u in 0..Math.PiTimes2..0.01)
	{
		x = 2+Math.Sin(v) * Math.Cos(u);
		y = Math.Sin(v) * Math.Sin(u);
		z = Math.Cos(v);

		arrPoints [u] = Point.ByCoordinates(x, y, z);

	}
	 return = arrPoints;
};

returns a list of 7 points
image

while I was expecting 629 points:
image

What am I missing? :face_with_monocle:

The u variable is a double but you’re using it to index into an array. Try adding a new integer index value like so:

1 Like

Thank you @Dimitar_Venkov for your answer. I am testing your suggestion but I get errors. If you substitute this

x = Math.Cos(u);
y = Math.Sin(u);
z = 0;

inside your for loop does it gives you a circle by any chance?

it also looks like you should change this to

arrPoints = []

{} actually creates a new dictionary, not a list.

If the result below is your objective, you might find it rewarding to start afresh with Associative code (avoid Imperative) using Design Script.

u1 = 0..Math.PI*2..#100;
a1 = Math.RadiansToDegrees(u1);

v1 = 0..Math.PI..#100;
a2 = Math.RadiansToDegrees(v1);

x1 = 2 + (Math.Sin(a2)<1> * Math.Cos(a1)<2>);
y1 = 2 * (Math.Sin(a2)<1> * Math.Sin(a1)<2>);
z1 = Math.Cos(a2)<1>;

p1 = Point.ByCoordinates(x1,y1,z1);
s1 = NurbsSurface.ByPoints(p1);
2 Likes

To get the full circle, you’ll need to convert the radians to degrees because the Sine and Cosine nodes expect their input to be in degrees.

By the way, if you’re only after spherical coordinates, you could also use the Point.BySphericalCoordinates node and by changing the scaling of the coordinate system input (cs), modify the overall shape:

2 Likes

This might be closer to the approach you’re attempting …

geometry = [Imperative]
{
	a = 0;
	b = 0;
	arrPoints = [];
	for (v in 0..180..5)
	{
		for (u in 0..360..5)
		{
			x = 2 + Math.Sin(v) * Math.Cos(u);
			y = Math.Sin(v) * Math.Sin(u);
			z = Math.Cos(v);
			arrPoints [a][b] = Point.ByCoordinates(x, y, z);
			b = b + 1;
		}
		a = a + 1;
		b = 0;
	}
	return List.Clean(NurbsCurve.ByPoints(arrPoints),false);
};
1 Like

Hello @Vikram_Subbaiah this is it! Thank you!!! :grinning:

However, if I change the parameters to match the following

Option Explicit
Dim v, Pi
For v = 0 To 2 * Pi Step .02
	SPHERE()
Next

Sub SPHERE() 
	Dim u
	Dim x, y, z
	Pi = 4 * Atn(1) 
	Dim arrPoints
	For u = Pi / 2 To 3 * Pi / 2 Step .02
		x = ((3 / 2) + sin(u + 2 * v)) * (cos(v) + cos(2 * v) / 10)
		y = ((3 / 2) + sin(u + 2 * v)) * (sin(v) + sin(2 * v) / 10)
		z = (sin(sin(cos(u + 2 * v) + cos(12 * u) / 12)))
		If IsArray(arrPoints) Then
			ReDim Preserve arrPoints ( UBound(arrPoints) +1)
		Else
			ReDim arrPoints(0)			
		End If
    	arrPoints(Ubound(arrPoints)) = Array(x, y, z)
	Next  		
	Rhino.AddCurve arrPoints
End Sub

expecting this as a result

ezgif.com-gif-maker

I come up with the following code

geometry = [Imperative]
{
	a = 0;
	b = 0;
	arrPoints = [];
	for (v in 0..2*180..2)
	{
		for (u in (180/2)..(3*180/2)..2)
		{
			x = ((3/2) + Math.Sin(u+(2*v))) * (Math.Cos(v)+Math.Cos(2*v)/10);
			y = ((3/2) + Math.Sin(u+(2*v))) * (Math.Sin(v)+Math.Sin(2*v)/10);
			z = (Math.Sin(Math.Sin(Math.Cos(u+(2*v))+Math.Cos(12*u)/12)));
			arrPoints [a][b] = Point.ByCoordinates(x, y, z);
			b = b + 1;
		}
		a = a + 1;
		b = 0;
	}
	return List.Clean(NurbsCurve.ByPoints(arrPoints),false);
};

that gives me this

can you spot the error?

1 Like

The nested Sin values are in Radians, will need to be converted to Degrees while obtaining Sin

I’ve also provided the Associative alternative below

Associative

u = 180/2..3*180/2..2;
v = 0..180*2..2;
x = ((3/2) + Math.Sin(u + (2 * v)<1>)) * (Math.Cos(v) + Math.Cos(2 * v)/10);
y = ((3/2) + Math.Sin(u + (2 * v)<1>)) * (Math.Sin(v) + Math.Sin(2 * v)/10);
z = Math.Sin(Math.RadiansToDegrees(Math.Sin(Math.RadiansToDegrees(Math.Cos(u + (2 * v)<1>)<1> + (Math.Cos(12 * u) / 12)))));
s = GeometryColor.ByGeometryColor(NurbsSurface.ByPoints(Point.ByCoordinates(x,y,z)),Color.ByARGB(150,255,150,100));

Imperative

geometry = [Imperative]
{
	a = 0;
	b = 0;
	arrPoints = [];
	for (v in 0..2*180..2)
	{
		for (u in (180/2)..(3*180/2)..2)
		{
			x = ((3/2) + Math.Sin(u+(2*v))) * (Math.Cos(v)+Math.Cos(2*v)/10);
			y = ((3/2) + Math.Sin(u+(2*v))) * (Math.Sin(v)+Math.Sin(2*v)/10);
			z = (Math.Sin(Math.RadiansToDegrees(Math.RadiansToDegrees(Math.Sin(Math.Cos(u+(2*v))+Math.Cos(12*u)/12)))));
			arrPoints [a][b] = Point.ByCoordinates(x, y, z);
			b = b + 1;
		}
		a = a + 1;
		b = 0;
	}
	return List.Clean(NurbsCurve.ByPoints(arrPoints),false);
};
2 Likes