# pouët.net

Go to bottom

## Any tips on creating this spiral torus effect?

category: code [glöplog]

Does anyone have ideas on creating this effect? I found a post on math stackexchange and they showed examples of a geodesic on a torus that seemed to be pretty close to the effect. It uses a parmaterized equation.
A link to wolfram alpha shows an example:

http://www.wolframalpha.com/input/?i=ParametricPlot3D[{Cos[Sqrtt]%283%2BCos[t]%29,+Sin[Sqrtt]%283%2B+Cos[t]%29,+Sin[t]},+{t,+0,+100}]

Ive been using evaldraw to experiment and have some code using the above formula:

https://pastebin.com/WV6iiNbd

The problem is using that parameterized equation. It would be nice to do it using raymarching but not sure the distance formula to get the stripes. It seems like there would be some hackish way to get the same thing.

I saw this effect in a recent c64 demo and it got me curious as to how it was done.
It'a gif anim!
Seriously, I believe it wan an animation in that c64 demo too.
My inspiration was the same gif
check my 256b intro
cmucc uses this image in the Demosplash opening ceremony each year - mdille3 or kbare might know.
Raymarching is the way to go.

Torus equation in cartesian coordinates is :

Code:`f(x,y,z) = (R - sqrt(x^2 + y^2))^2 + z^2 = r^2`

From there you can get your distance function.

Once you find the (x,y,z) intersection, map it back to (u,v) coordinates.

Then using (u,v), you can get your stripes.

with uv you can just apply your standard 3d rasterizer texture mapping...
Thanks for all the info. The experiments.withgoogle link used a polygonal torus with a striped texture mapped simply on it that looked good.

I figured there would be a shadertoy that someone had made. The key to it was how it calculated the stripes once you got the point on the surface:

float majorAngle = atan(rayPos.z, rayPos.x);
float minorAngle = atan(rayPos.y, length(rayPos.xz) - 4.0);
float edge = mod(8.0 * (minorAngle + majorAngle + iTime) / PI, 1.0);
Actually, there's a nice symmetry that emerges from expanding atan(x)+atan(y) in atan((x+y)/1-xy)). See second to last line

Code:``` void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 px = (2.0*fragCoord-iResolution.xy)/iResolution.y; vec3 ro = vec3(0.0, 0.0, -0.9); vec3 rd = normalize( vec3(px,1.0) ); vec3 po = ro; float k; for (int i = 0; i <50; i++) { k = length(po.xz) - 1.0; float h = 0.75-length(vec2(k,po.y)); po += h * rd; } float f = iTime + atan(k*po.z + po.x*po.y, k*po.x - po.z*po.y ); fragColor = vec4(8.0*sin(16.0*f)); } ```