Cookbook

Generating points

Ensure that pointwrangle is set to run over Detail

Stacking boxes

//user controls 
float size = chf("size");
int pt =  chi("numpt");

// OR reference box size with expressions
// float size  = `chs("/obj/Boxes/box4/sizey")`; // notice the backticks for expressions

for(int i =0 ;i<pt;i++){
    float x = 0;
    float y = i*size;
    float z = 0;
    v@loc = set(x,y,z);
    addpoint(0,v@loc);
}

Stacking spheres

//user controls 
int pt =  chi("numpt");
float size  = 2*`chs("/obj/SnowMan/sphere1/rady")`*`chs("/obj/SnowMan/sphere1/scale")`;

for(int i =0 ;i<pt;i++){
    float x = 0;
    float y = i*size;
    float z = 0;
    v@loc = set(x,y,z);
    addpoint(0,v@loc);
}

Circle

int pt = 18;
float angle = 360/pt;
float radius = 20;

for (int i = 0; i < pt; i++)
{
    float x = radius * cos(radians(angle * i));
    float y = radius * sin(radians(angle * i));
    float z = 0;
    v@loc = set(x, y, z); 
    addpoint(0,v@loc);
} 

Spirals

int points = chi("points");
float radius = chf("radius");
float freq = chf("freq");
float mul = chf("mul");
vector pos ={0,0,0};


pos.x = radius*sin(@Time*freq);
pos.y = radius*cos(@Time*freq);
pos.z = @Time*freq*mul;

addpoint(0,pos);

Phyllotaxis

Vogel’s formula

r=cnθ=n137.508r = c\sqrt n \\θ = n * 137.508

Parametric equations

x=cncos(n137.508)y=cnsin(n137.508)x = c \sqrt n*cos ( n * 137.508 )\\y= c \sqrt n*sin ( n * 137.508 )
// source: deborahrfowler.com

int total = chi("total");
float cval = ch("cval");
float zdepth = ch("zdepth");
float angle = 137.508;

void makephyllo(int total; float cval; float zdepth; float angle){
    float x,y,z;
    vector loc ={0,0,0};
    
    // set up the rotation azis variables to orient objects correctly onto the points
    // to do this, we will associate an orient attribute with each point;
    vector axis = {0,0,1};
    float radrotAngle;
    vector4 orient;

    for(int i =0;i<total;i++){
        x = cval *sqrt(i) * cos(radians(angle*i));
        y = cval *sqrt(i) * sin(radians(angle*i));
        z = i*zdepth;
        loc =set(x,y,z);
        
        // set up rotation - orient attribute
        radrotAngle = radians(angle*i);
        orient = quaternion(radrotAngle,axis);
        addpoint(geoself(),loc);
        
        // note that the addpointattrib creates the attribute, it is necesary to use setpointattrib to write the values
        addpointattrib(geoself(),"orient",orient);
        setpointattrib(geoself(),"orient", i, orient, "set");
        
        }
}
    
makephyllo(total,cval,zdepth,angle);
x=ρcosθsinϕy=ρsinθsinϕz=ρcosϕx = \rho cos\theta sin\phi\\y = \rho sin\theta sin\phi\\z=\rho cos\phi

Torus / Toroidal

x=(a+bcosu)cosvy=(a+bcosu)sinvz=bsinux=(a+bcosu)cosv \\ y=(a+bcosu)sinv\\ z=bsinu
// Attribute wrangle SOP (Detail mode) 

float vel = chf('vel');
int numpt = chi('Points');
float a = ch('a'); // completion
float b = ch('b'); // arc length
float u = ch('v'); // radius
vector pos; 

for(int i=1;i<numpt;i++){

    addpoint(0,pos);
    float offset = @ptnum*vel*i;
    addprim(0,"polyline",i);
    addvertex(0,1,i);
    pos.x = u*cos(a*offset)*sin(b*offset);
    pos.y = u*sin(a*offset)*sin(b*offset);
    pos.z = u*cos(offset*b); 
}
//  Have a geo & scatter sop before the wrangle node

float t = 1.0*@elemnum/@numelem ;

float completion = ch('completion') * 2 * $PI;
float coils = ch('coils');
float R = ch('outerRadius');
float r = ch('innerRadius');

float u = t * completion * coils ;
float v = t * completion ;

float x = cos(v)*(R+r*cos(u));
float y = sin(v)*(R+r*cos(u));
float z = r * sin(u);

@P = set(x,y,z);

//https://berniebernie.fr/wiki/Houdini_VEX

Mobius strip

x=[R+scos(½t)]cos(t)y=[R+scos(½t)]sin(t)z=ssin(½t)x = [ R + s cos(½ t)] cos(t)\\ y= [ R + s cos(½ t)] sin (t) \\ z = s sin(½ t)
//  Have a geo & scatter sop before the wrangle node

float completion = ch('completion');
float t = completion*@elemnum/@numelem ;
t += ch('vel');
float R = chf('radius'); 
float s = chf('s');
vector pos = @P;

float x = (R+s*cos(.5*t))*cos(t);
float y = (R+s*cos(.5*t))*sin(t);
float z = s*sin(0.5*t);

@P = set(x,y,z);
//https://berniebernie.fr/wiki/Houdini_VEX

Check out: https://www3.math.tu-berlin.de/geometrie/Lehre/SS17/MathVis/exercise01.pdf

Cardioid

Also check out: Times Tables, Mandelbrot and the Heart of Mathematics

Points transformation

Random pscale

@pscale = rand(@ptnum)
@pscale = fit01(@pscale, ch('min'),ch('max')); // fit within range 

Random delete points/prim/id

if(rand(@ptnum) > ch('threshold') ) {
   removepoint(0,@ptnum);
}

// shorthand
if rand(@pt)<ch('threshold') 
   removepoint(0,@ptnum);

Random 'pushing' along Normal

float factor = fit01(rand(@ptnum),chf('min'),chf('max'));

@N*=ch('scale')*factor;
@N = pow(@N,1.1);
@P= @N;

Rotation

Rotate to point to center

//orientVector_Lavrenov

@N = normalize(-@P);
v@side= normalize(cross(@up,@N));
float rot_amount = length(@P)*-chf("rotation_mul");

matrix3 m = ident();
rotate(m,rot_amount, @side);
@N = normalize(@N*m);
@up = normalize(@up*m);

Rotation with p@orient

float rotx = ch('rot_x');
float roty = ch('rot_y');
float rotz = ch('rot_z');
 
vector r = set(rotx,roty,rotz);
 
p@orient = eulertoquaternion(radians(r),XFORM_XYZ);

Rotating points with matrix

matrix3 m = ident(); // identity matrix creation
float angle = radians(chf("degrees")); // angles in radians
vector axis = {0,1,0}; // axis to turn

rotate(m,angle,2);
@P *= m;

Scale

Scale primitive locally with matrix & foreach

float scale = chf('scale');
vector nml = prim_normal(0, @primnum, {0,0,0});
int pts[] = primpoints(0, @primnum);
foreach(int pt; pts){
    matrix m = instance(v@P, nml, scale, {0,0,0}, {0,0,0,1}, v@P);
    vector pos = point(0, 'P', pt) * m;
    setpointattrib(0, 'P', pt, pos, 'set');
} 
// Source:https://www.sidefx.com/forum/topic/50477/?page=1#post-227472

Spreading points in one axis

@P.y = normalize(curlnoise(@P+@Time*.02)*0.5);
@pscale = rand(@ptnum);
@Cd = rand(@ptnum);

Color

Band(s) of color moving across geo in one-axis

@dir = @P.y;
float width = chf('width');
float offset = chf('offset');
float vel = chf('vel');
@Cd = sin(offset+width*@dir-@Time*vel);
@pscale = @Cd;

Oscillations

Sin wave

abs(sin(@Time*rand(@ptnum)+chf('Z')));

Using Cd for alpha

float u  = clamp(@value,,0,1); 
@Alpha = chramp('ramp_value'),u)

Connecting lines

Plexus — Entagma

float maxdist = chf('max_dist');
int npts[] = nearpoints(0,v@P,maxdist);

removeindex(npts,0);
i[]@npts = npts;

foreach(int npt; npts){
     addprim(0,"polyline",@ptnum,npt);
}
   

Type

Random character

 \\`int(fit01(rand($F),1,94))` 
 
 // use 65-90 for lower case letters.
 
 // Time Shift SOP
 stamp('../copy1','step',2)
 
 // copystamp SOP
  fit01(rand(@ptnum+$F+22),0,100)

Last updated