Handmade Hero » Forums » Game » Day 436: Rotating Spiral
Vkar
5 posts
#14603 Day 436: Rotating Spiral
1 month, 1 week ago Edited by on March 18, 2018, 11:01 p.m. Reason: Initial post

Hi,
we had some discussion in the chat.
Here is my take on the spiral.
Code is not meant to be good python, but to be readable.
Note I got rid of the first term for z, (1-1/N), as this creates a hole on the top.

Features:
-A factor to pronounciate the top (2.0 seems fine)
-Randomness, but only in z direction (this can of course be changed)
-Nice spatial pattern


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import random 

def NOZ(v):
    norm = np.linalg.norm(v)
    if norm == 0: 
       return v
    return v / norm
    
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
nrays = 16
nsub = 4
invtupdate = 20
factor = 2.0
randomratio = 0.02

n2 = nrays * nsub
n = n2 * 2
nodes = np.arange(n2) 
nodes2 = nodes ** factor / float(n2) ** (factor -1 )
colors = cm.rainbow(np.linspace(0, 1, invtupdate))
golden_angle = np.pi * (3 - np.sqrt(5))
for k in range(invtupdate):
    thetaoffset = 360/invtupdate*k/180.0*np.pi
    for l in range(n2):
        z =  (1-  (2.0 * nodes2[l]) / (n - 1))
        theta = nodes[l] * golden_angle
        radius = np.sqrt(1-z**2)
        xs = radius * np.cos(theta+thetaoffset)
        ys = radius * np.sin(theta+thetaoffset)
        z = z + random.uniform(randomratio, -1*randomratio)
        z = max(z,0)
        V = NOZ([xs, ys, z])
        ax.scatter(V[0], V[1], V[2], color=colors[k] )

ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
plt.show()




Every color is one frame.
Vkar
5 posts
#14617 Day 436: Rotating Spiral
1 month ago Edited by on March 19, 2018, 6:49 p.m.

In C:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
        random_series HemiSeries = Solution->Series;
        u32 N2 = 16*4;
        u32 N = 2 * N2;
        u32 invtupdate = 20;
        f32 randomratio = 0.02;
        f32 golden_angle = Pi32*(3.0f - SquareRoot(5.0f));
        u32 maxSampleCount = invtupdate;
        
        for(u32 SampleCount = 0;
            SampleCount < maxSampleCount;
            ++SampleCount)
        {
            GetCurrentQuads(Group, 64*6);
            f32 ThetaOffset = 360.0f / (f32)invtupdate*SampleCount / 180.0f*Pi32;
            
            for(u32 Index = 0;
                Index < 16;
                ++Index)
            {
                for(u32 SubIndex = 0;
                    SubIndex < 4;
                    ++SubIndex)
                {
                    f32 i = (f32)Index*4.0f + (f32)SubIndex;
                    
                    f32 Theta = golden_angle*i;
                    f32 z = (1.0f - ((2.0f*Square(i)/N2) / (N - 1)));
                    f32 Radius = SquareRoot(1.0f - z*z);
                    z = Clamp(0.0f, z + randomratio * RandomBilateral(&HemiSeries), 1.0f);
                    v3 Normal = {
                        Radius*Cos(Theta+ ThetaOffset),
                        Radius*Sin(Theta + ThetaOffset),
                        z };
                    

                    Normal = NOZ(Normal);

                    
                    PushCube(Group, Bitmap, StartPoint + 1.0f*Normal, 0.01f, 0.02f, V4(((f32)maxSampleCount - (f32)SampleCount-1)/ (f32)maxSampleCount, 0, ((f32)SampleCount) / (f32)maxSampleCount, 1));