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);
}
// change center to bottom for SOP
ch("sizey") * .5
//place expresssion into translate Y of a copy stamp node
ch("../box1/sizey") + $CY * ch("../box2/sizey")
// get bounding box og geometry
bbox("../merge1",D_YSIZE)
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);
}
// align sphere center to bottom
ch("rady")*ch("scale")
// reference scale
ch("../sphereBase/scale") * .8
// transform / stacking
ch("../sphereBase/rady") * 2 * ch("../sphereBase/scale")
+ ch("../sphereStomach/rady") * 2 * ch("../sphereStomach/scale")
// using bbox
bbox("../merge1",D_YSIZE)
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);
}
// copystamp
10 * cos(10 * $CY)
10 * sin(10*$CY)
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);
Source: David Kahl Polar Coordinates in Houdini
// 1st point wrangle
int points =chi("points");
float step = (PI*2)/ ch("steps");
vector pos;
float angle = chf("angle");
float radius = chf("radius");
for(int i=0; i<points;i++){
angle+= step;
radius = float(i)/ float(points);
pos.x = cos(angle) * radius;
pos.z = sin(angle) * radius;
addpoint(0,pos);
}
// 2nd point wrangle
float norm = float(@ptnum)/float(npoints(0));
@P.y=norm*chi("mult");
// 3rd point wrangle
for(int i= 0;i<npoints(0);i++){
int prim = addprim(0,"polyline");
addvertex(0,prim,i);
addvertex(0,prim,i+1);
}
Phyllotaxis
The Algorithmic Beauty of Plants - chapter 4, Springer-Verlag
Vogel’s formula
r=cnθ=n∗137.508
Parametric equations
x=cn∗cos(n∗137.508)y=cn∗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);
// Source: https://github.com/kiryha/Houdini/wiki//vex-snippets
int count = chi('points');
float bound = 10.0;
float tau = 6.28318530; // 2*$PI
float phi = (1+ sqrt(5))/2; // Golden ratio = 1.618
float golden_angle = (2 - phi)*tau; // In radians(*tau)
vector pos = {0,0,0};
float radius = 1.0;
float theta = 0;
int pt;
vector polar_to_cartesian(float theta; float radius){
return set(cos(theta)*radius, 0, sin(theta)*radius);
}
for (int n=0; n<count; n++){
radius = bound * pow(float(n)/float(count), ch('power'));
theta += golden_angle;
pos = polar_to_cartesian(theta, radius);
// Create UP, pscale and N attr
pt = addpoint(0, pos);
setpointattrib(0, "pscale", pt, pow(radius,0.5));
setpointattrib(0, "N", pt, normalize(-pos));
setpointattrib(0, "up", pt, set(0,1,0));
}
//formula
c * sqrt( $CY ) * cos ( $CY * angle )
// with correct values
2 * sqrt( $CY ) * cos( $CY * 137.508 ) i
x=ρcosθsinϕy=ρsinθsinϕz=ρcosϕ
Torus / Toroidal
x=(a+bcosu)cosvy=(a+bcosu)sinvz=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
float t = 3.0*@elemnum/@numelem ;
float a = ch('a'); // radius
float b= ch('b'); // inner radius
float u = ch('u')*t; // coils
float v = ch('v')*t; // completion
float x = (a+b*cos(u))*cos(v);
float y = (a+b*cos(u))*sin(v);
float z = b*sin(u);
v@P = set(x,y,z);
//https://math.stackexchange.com/questions/324527/do-these-equations-create-a-helix-wrapped-into-a-torus
Mobius strip
x=[R+scos(½t)]cos(t)y=[R+scos(½t)]sin(t)z=ssin(½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
float scale = chf('scale');
int pts[] = primpoints(0, @primnum);
foreach(int pt; pts){
vector pos_pt = point(0, 'P', pt);
vector dir = normalize(pos_pt - v@P);
vector pos = pos_pt + dir * scale;
setpointattrib(0, 'P', pt, pos, 'set');
}
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