This is part of a series of small exercises and experiments I am doing in Houdinis VEX language. There might be better ways to solve this and if I discover a better way I will update the post.
In my effort to create a city created procedurally I needed an easy way to control curves on a terrain. The first thing was to be able to displace a curve to create a road. I know this can be done with the standard tools in Houdini but I wanted more control of the result so I decided to do it through VEX.
The curve needs to be flat in the XZ plane (I will displace the curve in the y direction to fit the terrain later). I added parameters for random distance and rotation around Y (orientation).
int f = 1; if (ch('../dispMirror') == 1) f = -1; //DISPLACE POINTS vector a; if (@ptnum == 0) { a = normalize(point(0, "P", @ptnum+1) - point(0, "P", @ptnum)); } if (@ptnum >= 1) { a = normalize(point(0, "P", @ptnum+1) - point(0, "P", @ptnum-1)); } if (@ptnum == npoints(0)-1) { a = normalize(point(0, "P", @ptnum)- point(0, "P", @ptnum-1)); } int rd = int(random(@ptnum)*ch('../dispRand')); @P += set(-a.z, 0, a.x) * ((ch('../dispDist')/2) + rd) * f; //Rotate Points in XZ-Plane //Initialize Up and N vector rotAxis = set(0,1,0); // Set up Vector to Y (we're working on '2D' here) vector N = a; //select the Axis // create a 3x3 orientation matrix using N and up as the principal axes. matrix3 m = maketransform(N, rotAxis); // now rotate this matrix around the N axis float angle_deg = (f * 90) + ch('../rot') + ((random(@ptnum)-.5)*2) * ch('../rotRand'); float angle = radians(angle_deg); rotate(m, angle, rotAxis); p@orient = quaternion(m);