Obsidian: [[08-01-01-V_Expressions]] [[09-01-01-V_Attribs]] [[10-01-01-V_Syntax]] [[07-01-01-V_Strings]] [[03-01-01-V_Measure]] [[03-_V_Curves]]
Angle
f@angle = degrees(acos(dot(normalize(a),normalize(b)))); - Angle Between Vectors
Sort points in cirlcle.
vector center = getbbox_center(0);
vector dir = normalize(@P-center);
f@sortval = atan2(dir.x, dir.z);
Nomenclature
Houdini operate in radians
revolution rev 0-1 - 1 full circle = 1 rev = 1 turn = 1 rot = 360°
degrees 0-360° - Measure angles by how far we tilted our heads- observer viewpoint
radians 2πr ~6.283.. - Measure angles by distance traveled - movers viewpoint
euler angle - Direction 3Vector
dihedral angle - Angle between two intersecting planes.
matrix3 m = ident(); - no rotation form of @orient matrix 3 is rot matrix, matrix 4 is full transform.
Transform hierarchy
Order of rotation determine output. Use one transform at a time by priority:
v@pivotexists, use it as the local transformation of the copy/inst. If not:4@transformattribute exists: Use it as Transformmatrix, overriding everything except P/pivot/transp@orientUse it to orient (Copy to point SOP) result of your rotation matrix as a quaternionv@N+v@upas the +Z axis and up as +Y axis.v@vVelocity of the copy (motion blur, and used as +Z axis of the copy if no orient or N)p@rot(quaternion) - Additional Q rotation, (applied after the orientation attributes above)f@pscale- Uniform (multiplied by @scale if it exists).v@scaleNon-uniformscale(3@transform, vector(@pscale));(transform:1!)v@transexists, use it and P to move the copy/instance. - Translation of the copy, in addition to Pv@P- Translation of the copy - Instance Position
Copy To Points
- Z-axis points towards N (Objects must be oriented to +Z)
- @orient (Quaternion)
N - z align to
up - Y align to
Translate
Translate Matrix
matrix translate_matrix = ident();
translate(translate_matrix, chv("translation"));
translate_matrix*=m;
@P*=translate_matrix;
@cracktransform()- returns value of rotation scale or translate from a matrix
Rotate
f@Degrees = degrees(@Radians) - 0-6.283 to: 0-360 (radians to degrees)
f@Radians = radians(@Degrees) - 0-360 to: 0-6.283 (degree to radians)
Matrx
construct with: (3@ = rot, 4@ = full transform)
Can rotate object (poonts???) by matrix multiplication v@P *= m.
- if you multiplay by identity matrix nothing will change
- Introduction to matrices
Rotate Object with Matrix about given axis Can roatate about calculated tangent (axis=tangent)!
vector axis = normalize(chv("rot_axis"));
float a = radians(chf('rot_amount')*360); /// euler angle
matrix3 m = ident();
rotate(m, a, axis); // rotate matrix
@P *= m;
// rotate back matrix
@P*=invert(m);
Look at
vector current_axis = {0,0,0};
vector up_axis = {0,1,0};
vector lookat_axis = point(1, "P", 0);
matrix3 m = lookat(current_axis, lookat_axis, up_axis);
@P *= -m;
Euler
(Vector) construct with: (v@N (Z align) and v@up (Y align), v@EulerAngle)
v@Angle = set(@Radians,0,0) - Euler angle
@quaterniontoeuler - returns Euler angles from a quaternion
p@orient = eulertoquaternion(@EulerAngle, 0) - (euler to quat)
@dihedral - returns the quaternion that points vector A to vector B.
Quaternions
Convert
@orient = quaternion(maketransform(@N,@up)); - (make orient from N & up )
@orient = quaternion(f@angle, normalize(v@axies)); - ( make orient from Angle and Vector )
@orient = quaternion(normalize(axis)*@AmountOfTot); - scale axis vec to get amount
@orient = quaternion(m); - by matrix (matrix3 m = ident();)
@orient = slerp(a, b, ch('blend') ); - blend oreints
@orient = qmultiply(@orient, extrarot); -
Look at - Dihedral
Computes the rotation matrix or quaternion which rotates the vector a onto the vector b
vector target = chv("target");
vector4 q = dihedral({0,1,0}, target);
@P = qrotate(q,@P);
Orient points
Rotate Individual Points
Set rotation in direction composed by N & up. and create the orient quaternion as a point attribute
float a = ch("Angle");
vector up = normalize(chv('Up'));
vector N = normalize(chv('N'));
matrix3 m = maketransform(N, up);
rotate(m, a, N);
@orient = quaternion(m);
Quat to Matrix > apply transform » quat Quaternion , Matrix Rotate
matx = qconvert(orient_tmp); / quaternion orietnt to matrix
rmatrix = vop_rotate(matx, angle, axis); / rotate
orient = quaternion(rmatrix); / apply matrix to quat
Set default orient by matrix
vector N = chv("N");
vector up = normalize(chv('Up'));
vector z = N;
vector x = normalize(cross(up, N));
vector y = normalize(cross(N, x));
matrix3 m_default = set(x, y, z);
@orient = quaternion(m_default);
Set direction with directing
Double cross product has the effect of “directing” the vectors
vector vec = {0,-1,0}; // vector to tend normals in this direction
@N = cross(cross(@N, vec), @N);
Rotate Object
Quaternion in local space (Run over points)
vector eulerAngle = radians(chv("rot")); // angle in degrees converted to radians
vector4 quat = eulertoquaternion(eulerAngle, 0);
matrix3 m3 = qconvert(quat);
matrix m = set(m3);
@P *= m;
if xform is present set attrib before @P:
if (hasdetailattrib(0, "xform")){
matrix inputXform = detail(0,"xform");
@P*=invert(inputXform);
m*=inputXform;
}
setdetailattrib(0,"xform",m); // store xform in detail
Store xform in Attribute to return it to the original position
4@xform_matrix = xform;
@P *= invert(4@xform_matrix);
Packed geometry
Packed Geometry Rotate
(Run over Prims)
OpInput0: packed geo
matrix3 x = primintrinsic(0, "transform", @primnum); // matrix3 x = ident();
vector axis = normalize(chv("axis"));
float euler_angle = radians(chf("angle"));
rotate(x, euler_angle, axis);
setprimintrinsic(0, "transform", @primnum, x, "set");
Get Orient from packed
matrix m = primintrinsic(0, "packedfulltransform", @primnum);
matrix3 m3 = matrix3(m);
p@orient = quaternion(m3);
Get Pivot from packed
vector3 pivot = primintrinsic(0, "pivot", @primnum);
v@pivot = pivot;
Packed Geometry from RDB to copy to object https://youtu.be/W9ggbLr6wNY?t=1001 To transform to replace low proxy in RDB. Copy intrinsic transforms to points:
matrix m4 = primintrinsic(0,'packedfullytransform', @ptnum);
matrix3 m3 = matrix3(m4);
@orient = quaternion(m3);
@scale = cracktransform(0,0,2,0,m4);
v@pivot = primintrinsic(0,'pivot',@ptnum);
Orient piece of geometry by 4 points: {@vux}
- src_pt - source point 1
- dst_pt - destination point 1
- src_opt - source point 2
- dst_opt - destination point 2
int src_pt = 10 ;
int dst_pt = 2 ;
int src_opt = 11 ;
int dst_opt = 3 ;
vector4 q = dihedral( point(geoself(), “P”, src_pt)-point(geoself(), “P”, src_opt),
point(geoself(), “P”, dst_pt)-point(geoself(), “P”, dst_opt) );
@P = qrotate(q, @P)+point(geoself(), “P”, dst_pt)-qrotate(q, point(geoself(), “P”, src_pt));
perfect loop: sin(2*PI*(@Time*frequency + offset))
https://www.toadstorm.com/blog/?p=493
http://www.tokeru.com/cgwiki/?title=Copy,_Stamps,_Rotation,_Hscript,_Vex,_a_ramble
http://www.tokeru.com/cgwiki/index.php?title=JoyOfVex17#Combine_orients_with_qmultiply
http://yoong-cut-and.blogspot.com/2014/12/orienting-objects-to-curve-basic-of.html
https://vimeo.com/307156961
Direction
Directional Bias
2D
u@P += sample_circle_uniform(rand(@ptnum)); - pos in circle
u@P += sample_circle_edge_uniform(rand(@ptnum)); - pos in circumference
u@P += sample_circle_slice(chu("direction"),chf("cone"),rand(@ptnum)); - pos in circle sector
u@P += sample_circle_arc(chu("direction"),chf("cone"),rand(@ptnum)); - pos in circumference arc
3D
v@P += sample_direction_uniform(rand(@ptnum)); - pos in sphere surface (Uniform Distribution)
v@P += sample_sphere_uniform(rand(@ptnum)); - pos in sphere volume (Normalized)
v@P += sample_direction_cone(chv("angle"),ch("cone"),rand(@ptnum)); - pos in spherical sector. (Control Range)
v@P += sample_sphere_cone(chv("angle"),ch("cone"),rand(@ptnum)); - pos in spherical cap. (Control Range Normalized)
4D
p@p = sample_hypersphere_uniform() - pos in hypersphere surface
p@p = sample_orientatnion_uniform() - pos in hypersphere volume (Normalized)
p@p = sample_orientation_cone() - pos in hypersphere sector. (Control Range)
@orient = sample_orientation_cone(quaternion(maketransform(@N,@up)),ch("cone"),rand(@ptnum));
p@p = sample_hypersphere_cone() - pos in hypersphere sector. (Control Range Normalized)
v@v = sample_hemisphere({0,0,1},@bias,u); -
https://vimeo.com/226167508
Direction to surface
(double cross)
https://voxelpixel.xyz/2020/06/05/vectors-double-cross-product/
—
Wave on plane (Points)
float range = chf('Range');
float angle = chf('Angle');
float bias = chf('Bias');
matrix m = ident();
vector axis = {0, 0, 1};
vector pos = @P;
pos.z *= bias;
float amount = exp(length(pos) / range * -1 );
amount = radians(amount * angle);
rotate(m, amount, axis);
@P *= m;
https://thenumbat.github.io/Exponential-Rotations/