Close

This May Be or May Knot Be Such a Good Idea?

A project log for Deep Sneak: For Lack of a Better Name

The mixture-of-experts and multi-model meme is in play, so lets let the reindeer games begin, even if we missed Christmas with Deep-Seek.

glgormanglgorman 02/19/2025 at 18:020 Comments

First. let's take a look back at something that I was working on last summer, and that is my very happy "Teapot in  the Garden" Rendering.

How nice! Yes. how very nice indeed!  Because I just saw something in the news the other day that NVIDIA has just announced their own Tensor Flow AI-based hair drawing routines, that supposedly allow for something like 240FPS rendering, and stuff like that, i.e., by requiring a 97% reduction in CPU/GPU utilization.  O.K., now that THEY are finally getting their act together, I must contemplate therefore: can we do better?  Well, for now, I am happy with my shader - even if it still mostly running on CPU + Open GL.  Yet here might be another possible use for Deep Seek, maybe?  I mean to say that is if I can get Deep Seek running, with or without Py-Torch in my own framework.  So let's do something else, therefore, like revisiting the whole theory of braids, that is - since the shader is pretty much ready for use in production code.

So yesterday I went on a coding binge - and started writing some code to do some simple GDI-based drawing of some braids, and for starters - I came up with a simple twist drawing routine.

After playing with the code, I finally came up with this mess - which might not be as terrible as it looks, since at least am at the point where the overall topology is mostly correct, even though there are obviously some alignment issues with how the different segments are being assembled, and this is something that I want to discuss further.

But first, let's have another view along the x-axis, i.e. so that we are looking at a projection, mostly of the YZ plane.

Now to understand what is happening here, take at look at the code for the "xyz" function:

_vector twist::xyz (MATH_TYPE l, int i)
{
    MATH_TYPE theta,x1,y1,dz;
    theta = l*(TWO_PI/180.0);
    x1 = m_width*(-cos(theta*0.5));
    if (i%2==0)
    y1 = m_radius*(1-cos(theta));
    else
    y1 = -m_radius*(1-cos(theta));
    dz = l*m_length*(1/360.0);
    _vector result (x1,y1,dz);   
    return result;
}

void braid::set_colors(int i)
{
    const COLORREF r = (int)COLOR::red;
    const COLORREF g = (int)COLOR::green;
    const COLORREF b = (int)COLOR::blue;
    struct ctab
    {
    COLORREF c[3];    
    };
    ctab colors[] =
    {
    {r,g,b},
    {b,g,r},
    {g,b,r},
    {r,b,g},
    {b,r,g},
    {g,r,b},
    };
    c1 = colors[i].c[0];
    c2 = colors[i].c[1];
    c3 = colors[i].c[2];
}

Elsewhere, of course, I am calling the "xyz" function to find the values of some points along my control lines for my braid, while also calling another function in the same set of loops in order to decide what color to draw each segment with.   The segment coloring function, is of course magic, since it relies on various permutations which I derived empirically, and put into a table lookup.  Yet. for efficiency reasons, this might be a better way, I hope than trying to deduce some other magic formula that looks at the layer index and strand id and which then tries to use division and or modular arithmetic to determine the type of strand to draw, whether it goes over or under, and how to color it.  So I'll live with it - for now.  Yet clearly something needs to be done with that xyz function - and how it is being invoked.

Maybe I could treat the position of my control lines as complex numbers in the xy plane, and then treat the z-axis as time, and then compute the Fourier transform of the functions that define the position of each strand.  Then a little low-pass filtering might yield a smoother function.  With a smoother function, then - why not take the low-pass filtered data, and generate some coefficients of some low-ordered polynomials, so that the xyz function might be computable for each strand according to some overlapped piecewise cubic interpolation?  Maybe this is a good place to mention that I hate Beziers!

This is only going to get more complicated when I get around to drawing bundles - instead of control lines, since then it will become necessary to take into account the collision and frictional properties of the bundle vs. bundle interactions - which right now, at least for the moment, seems to suggest that the collision mechanics might benefit computationally in terms of managing not just the topological domain aspect of each bundle, but how the collision domains interact between the associated realms - to use a more traditional vocabulary.

Perhaps transformers could be used; for example - to condition a network in such a way, as one might want to derive meshes from scalar data, via a traditional approach, such as "marching cubes", while at the same time, providing mesh vs. mesh interactions which would necessitate providing feedback - let's say - all the way back to how we might compute the FFT coefficients for our control vectors.  Which seems to look a lot more like a kind of transformer-based generative adversarial network - whether it generates the meshes and vector fields directly, or whether it runs alongside and controls the algorithms, i.e., by fine-tuning the procedural mesh generation according to the necessary constraints.

Discussions