Expanding or Shrinking a Helix Using Peak

   1390   5   0
User Avatar
Member
57 posts
Joined: Feb. 2017
Offline
Hi guys,

I guess that if I want to use the peak sop on a helix (that I have no control over the parameters of it) in order to expand it radially then I need to set the normal vectors by using the cross product of the point velocity between two consecutive points and one more cross product between the resulting vector and the velocity vector of one of those two points. Am I right or wrong? If I am right then would you please help me with the vex code for that?
Edited by fred_98 - Feb. 8, 2024 15:54:15
User Avatar
Member
2629 posts
Joined: June 2008
Offline
Just recreate the helix using the helix node. The peak node can only push points so far before uglifying the mesh.
Using Houdini Indie 20.0
Windows 11 64GB Ryzen 16 core.
nVidia 3050RTX 8BG RAM.
User Avatar
Member
57 posts
Joined: Feb. 2017
Offline
Sorry for not giving enough details but I am not interested only in the result. I want to learn the process of assigning normal vectors to helical shapes (and other non-uniform curved objects in future).
User Avatar
Member
209 posts
Joined: March 2018
Offline
You can add a PolyFrame node and set the Bitangent parameter to N before your Peak node.
It creates the desired normal vector for your helix.
Edited by N-G - Feb. 8, 2024 18:18:50
User Avatar
Member
57 posts
Joined: Feb. 2017
Offline
Thanks a lot,
Can I also get the same result using vex(for educational purposes)? please.
User Avatar
Member
4730 posts
Joined: Feb. 2012
Offline
Here is one way using a Primitive Wrangle:

vector computePerpendicularVector ( vector v )
{
    vector v0 = normalize ( v );
        
    vector y = { 0, 1, 0 };
    vector pv0 = y - ( v0 * dot ( v0, y ) );
    
    vector z = { 0, 0, 1 };
    vector pv1 = z - ( v0 * dot ( v0, z ) );
    
    if ( length2 ( pv0 ) > length2 ( pv1 ) )
        return normalize ( pv0 );
    
    return normalize ( pv1 );
}

int vtxcount = primvertexcount ( 0, @primnum );
if ( vtxcount > 1 )
{
    int pts [ ] = primpoints ( 0, @primnum );
   
    int count = len ( pts );
    
    int isclosed = primintrinsic ( 0, "closed", @primnum );
    if ( pts [ 0 ] != pts [ -1 ] )
    {
        if ( isclosed )
            append ( pts, pts [ 0 ] );
        else
            append ( pts, pts [ -2 ] );
    }
    else
    {
        removeindex ( pts, -1 );
        isclosed = 1;
        count -= 1;
    }
    
    vector tangents [ ] = { };
    vector normals [ ] = { };
    vector bitangents [ ] = { };
    resize ( tangents, count );
    resize ( normals, count );
    resize ( bitangents, count );
    
    for ( int i = 0; i < count; ++i )
    {
        vector p0 = point ( 0, "P", pts [ i ] );
        vector p1 = point ( 0, "P", pts [ i + 1 ] );
        
        vector tangent = normalize ( p1 - p0 );
        if ( isclosed == 0 && i == count - 1 )
            tangent *= -1;
            
        tangents [ i ] = tangent;
    }
    
    vector n = normalize ( cross ( computePerpendicularVector ( tangents [ 0 ] ), tangents [ 0 ] ) );
    normals [ 0 ] = normalize ( cross ( tangents [ 0 ], n ) );
    
    for ( int i = 0; i < count - 1; ++i )
    {
        vector bitangent = cross ( tangents [ i ], tangents [ i + 1 ] );
        if ( length2 ( bitangent ) < 0.0000001 )
            normals [ i + 1 ] = normals [ i ];
        else
        {
            bitangent = normalize ( bitangent );
            float angle = atan2 ( length ( cross ( tangents [ i ], tangents [ i + 1 ] ) ), dot ( tangents [ i ], tangents [ i + 1 ] ) );
            matrix3 rMatrix = ident ( );
            rotate ( rMatrix, angle, bitangent );
            normals [ i + 1 ] = rMatrix * normals [ i ];
        }
        bitangents [ i ] = bitangent;
    }
    
    for ( int i = 0; i < count; ++i )
    {
        if ( chi("normal") )
            setpointattrib ( geoself ( ), chs("n"), pts [ i ], normals [ i ] );
        if ( chi("tangent") )
            setpointattrib ( geoself ( ), chs("t"), pts [ i ], tangents [ i ] );
        if ( chi("bitangent") || ( chi("orient") || chi("rmatrix") ) )
        {
            bitangents [ i ] = normalize ( cross ( normals [ i ], tangents [ i ] ) );
            if ( chi("bitangent") )
                setpointattrib ( geoself ( ), chs("b"), pts [ i ], bitangents [ i ] );
        }
        matrix3 m = 0;
        if ( chi("orient") || chi("rmatrix") )
        {
            m = set ( bitangents [ i ], normals [ i ], tangents [ i ] );
            if ( chi("orient") )
                setpointattrib ( geoself ( ), chs("o"), pts [ i ], quaternion ( m ) );
            if ( chi("rmatrix") )
                setpointattrib ( geoself ( ), chs("rm"), pts [ i ], m );
        }
    }
}

chi parameters are toggles, chs parameters are attribute names.

Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

youtube.com/@pragmaticvfx | patreon.com/animatrix | pragmaticvfx.gumroad.com
  • Quick Links