Expanding or Shrinking a Helix Using Peak

   2450   5   0
User Avatar
Member
63 posts
Joined: 2月 2017
オフライン
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 - 2024年2月8日 15:54:15
User Avatar
Member
2658 posts
Joined: 6月 2008
オフライン
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.5
Windows 11 64GB Ryzen 16 core.
nVidia 3060RTX 12BG RAM.
User Avatar
Member
63 posts
Joined: 2月 2017
オフライン
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
213 posts
Joined: 3月 2018
オフライン
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 - 2024年2月8日 18:18:50
User Avatar
Member
63 posts
Joined: 2月 2017
オフライン
Thanks a lot,
Can I also get the same result using vex(for educational purposes)? please.
User Avatar
Member
5109 posts
Joined: 2月 2012
オフライン
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] https://lnk.bio/animatrix [lnk.bio]
  • Quick Links