### OSLHelix

#### Introduction

This page presents a shader that can be used to "cut" a helix with a central axis aligned to the Y axis. Figure 1

Listing 1 - helix.osl

 ```// Author: Malcolm Kesson // May 2019 shader helix ( float pitch = 1 [[ string label = "Pitch", ]], float width = 0.5 [[ string label = "Width", ]], int coordspace = 0 [[ string label = "Coordinate Space", string widget = "mapper", string options = "object:0|world:1|camera:2|user defined:3", ]], string userspace = "place3dTexture1" [[ string label = "User Defined", ]], output float resultMask = 0) { float half_width = width/2; // Convert the shading point to a specific coordinate system. point p; if(coordspace == 0) p = transform("object", P); else if(coordspace == 1) p = transform("world", P); else if(coordspace == 2) p = transform("camera", P); else p = transform(userspace, P); // Get the coordinates of the transformed shading point. float x = p; float y = p; float z = p; // Count the number of times the helix has looped around. float loops = floor( fabs(y) / pitch); // Calculate for the current loop the percentage rotation (theta) // the shading point. float theta = (atan2(x, z)); // To prevent a counter-rotation of the helix when the shading // point is below the origin of the coordinate system... if(y < 0) theta = theta * -1.0; theta = (theta + M_PI) / M_2PI; // When the shading point is near to the bottom or the top of the // current loop we ensure the final test takes lower and top // loops into consideration. float y_prev_loop = theta * pitch + (loops - 1) * pitch; float y_this_loop = theta * pitch + loops * pitch; float y_next_loop = theta * pitch + (loops + 1) * pitch; y = fabs(y); if( fabs(y - y_prev_loop) <= half_width || fabs(y - y_this_loop) <= half_width || fabs(y - y_next_loop) <= half_width) { resultMask = 1; } else { resultMask = 0; } } ```