<p>As you will see in the code, the tori are multiplied together, and a non-zero isovalue is used.</p>
<p>The final code is at: <a href="https://github.com/sjhalayka/k-genus_torus" rel="nofollow noreferrer">https://github.com/sjhalayka/k-genus_torus</a></p>
<p><a href="https://i.sstatic.net/r38ND.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/r38ND.png" alt="genus 5 tori" /></a></p>
<p><a href="https://i.sstatic.net/erb2G.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/erb2G.png" alt="enter image description here" /></a></p>

CC BY-SA 4.0
2023-11-16T13:56:43.643Z
did you use some library to implement that?
rnwed_user
CC BY-SA 4.0
2023-11-16T15:51:26.443Z
The code is all open source. I used some of the code from Paul Bourke's website -- https://paulbourke.net/geometry/polygonise/ --, and the rest of the code is mine. No external libraries are needed.
shawn_halayka
CC BY-SA 4.0
2023-11-11T03:54:57.727Z
2023-11-11T04:02:21.793Z
2023-11-11T04:02:21.793Z
shawn_halayka
<p>I've been trying to implement this k-torus code that I found, but all it does is return a cylinder (torus of outer radius infinity). Is there anything that I'm missing here?</p>
<pre><code>#include &quot;main.h&quot;

float f(const float x, const int n)
{
    float result = 1.0;

    for(int i = 1; i &lt;= n; i++)
    {
        const float i_float = static_cast&lt;float&gt;(i);

        result *= (result - (i_float - 1.0f)) * (result - i_float);
    }

    return result;
}

float g(const float x, const float y, const int n) 
{
    return f(x, n) + powf(y, 2.0);
}

float h(const float x, const float y, const float z, const int n, const float r, const float R)
{
    return powf(g(x, y, n), 1.0) + powf(z, 2.0) - powf(r, 2.0);
}


int main(void)
{
    const float grid_max = 10.0;
    const float grid_min = -grid_max;
    const size_t res = 100;
    const bool make_border = true;
    const float isovalue = 0.1f;
    const float border_value = 1.0f + isovalue;
    const int n = 2;
    const float radius = 0.1f;
    const float outer_radius = 1.0f;


    vector&lt;triangle&gt; triangles;
    vector&lt;float&gt; xyplane0(res*res, 0);
    vector&lt;float&gt; xyplane1(res*res, 0);

    const float step_size = (grid_max - grid_min) / (res - 1);

    size_t z = 0;

    vertex_3 pos(grid_min, grid_min, grid_min);

    // Calculate xy plane 0.
    for (size_t x = 0; x &lt; res; x++, pos.x += step_size)
    {
        pos.y = grid_min;

        for (size_t y = 0; y &lt; res; y++, pos.y += step_size)
        {
            if (true == make_border &amp;&amp; (x == 0 || y == 0 || z == 0 || x == res - 1 || y == res - 1 || z == res - 1))
                xyplane0[x * res + y] = border_value;
            else
                xyplane0[x * res + y] = h(pos.x, pos.y, pos.z, n, radius, outer_radius);
        }
    }

    // Prepare for xy plane 1.
    z++;
    pos.z += step_size;

    size_t box_count = 0;

    // Calculate xy planes 1 and greater.
    for (; z &lt; res; z++, pos.z += step_size)
    {
        pos.x = grid_min;

        cout &lt;&lt; &quot;Calculating triangles from xy-plane pair &quot; &lt;&lt; z &lt;&lt; &quot; of &quot; &lt;&lt; res - 1 &lt;&lt; endl;

        for (size_t x = 0; x &lt; res; x++, pos.x += step_size)
        {
            pos.y = grid_min;

            for (size_t y = 0; y &lt; res; y++, pos.y += step_size)
            {
                if (true == make_border &amp;&amp; (x == 0 || y == 0 || z == 0 || x == res - 1 || y == res - 1 || z == res - 1))
                    xyplane1[x * res + y] = border_value;
                else
                    xyplane1[x * res + y] = h(pos.x, pos.y, pos.z, n, radius, outer_radius);
            }
        }

        tesselate_adjacent_xy_plane_pair(
            box_count,
            xyplane0, xyplane1,
            z - 1,
            triangles,
            isovalue,
            grid_min, grid_max, res,
            grid_min, grid_max, res,
            grid_min, grid_max, res);

        xyplane1.swap(xyplane0);
    }

    cout &lt;&lt; endl;

    if (0 &lt; triangles.size())
        write_triangles_to_binary_stereo_lithography_file(triangles, &quot;out.stl&quot;);

    // Print box-counting dimension
    // Make sure that step_size != 1.0f :)
    cout &lt;&lt; &quot;Box counting dimension: &quot; &lt;&lt; logf(static_cast&lt;float&gt;(box_count)) / logf(1.0f/step_size) &lt;&lt; endl;


    return 0;
}
</code></pre>
<p><a href="https://i.sstatic.net/iZYnf.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/iZYnf.png" alt="enter image description here" /></a></p>
<p>The relevant documents are at:</p>
<p><a href="https://computergraphics.stackexchange.com/questions/13794/procedural-generation-of-genus-k-tori-triangle-meshes">Procedural generation of genus $k$ tori triangle meshes</a></p>
<p>and</p>
<p><a href="https://math.stackexchange.com/questions/152256/implicit-equation-for-double-torus-genus-2-orientable-surface">https://math.stackexchange.com/questions/152256/implicit-equation-for-double-torus-genus-2-orientable-surface</a></p>
<p>and</p>
<p><a href="https://github.com/sjhalayka/k-torus" rel="nofollow noreferrer">https://github.com/sjhalayka/k-torus</a></p>

<computational-geometry>
k-torus code in C++
shawn_halayka
# k-torus code in C++

(Asked by: username_0 on 2023-11-08)

I've been trying to implement this k-torus code that I found, but all it does is return a cylinder (torus of outer radius infinity). Is there anything that I'm missing here?

```
#include "main.h"

float f(const float x, const int n)
{
    float result = 1.0;

    for(int i = 1; i <= n; i++)
    {
        const float i_float = static_cast<float>(i);

        result *= (result - (i_float - 1.0f)) * (result - i_float);
    }

    return result;
}

float g(const float x, const float y, const int n) 
{
    return f(x, n) + powf(y, 2.0);
}

float h(const float x, const float y, const float z, const int n, const float r, const float R)
{
    return powf(g(x, y, n), 1.0) + powf(z, 2.0) - powf(r, 2.0);
}

int main(void)
{
    const float grid_max = 10.0;
    const float grid_min = -grid_max;
    const size_t res = 100;
    const bool make_border = true;
    const float isovalue = 0.1f;
    const float border_value = 1.0f + isovalue;
    const int n = 2;
    const float radius = 0.1f;
    const float outer_radius = 1.0f;

    vector<triangle> triangles;
    vector<float> xyplane0(res*res, 0);
    vector<float> xyplane1(res*res, 0);

    const float step_size = (grid_max - grid_min) / (res - 1);

    size_t z = 0;

    vertex_3 pos(grid_min, grid_min, grid_min);

    // Calculate xy plane 0.
    for (size_t x = 0; x < res; x++, pos.x += step_size)
    {
        pos.y = grid_min;

        for (size_t y = 0; y < res; y++, pos.y += step_size)
        {
            if (true == make_border && (x == 0 || y == 0 || z == 0 || x == res - 1 || y == res - 1 || z == res - 1))
                xyplane0[x * res + y] = border_value;
            else
                xyplane0[x * res + y] = h(pos.x, pos.y, pos.z, n, radius, outer_radius);
        }
    }

    // Prepare for xy plane 1.
    z++;
    pos.z += step_size;

    size_t box_count = 0;

    // Calculate xy planes 1 and greater.
    for (; z < res; z++, pos.z += step_size)
    {
        pos.x = grid_min;

        cout << "Calculating triangles from xy-plane pair " << z << " of " << res - 1 << endl;

        for (size_t x = 0; x < res; x++, pos.x += step_size)
        {
            pos.y = grid_min;

            for (size_t y = 0; y < res; y++, pos.y += step_size)
            {
                if (true == make_border && (x == 0 || y == 0 || z == 0 || x == res - 1 || y == res - 1 || z == res - 1))
                    xyplane1[x * res + y] = border_value;
                else
                    xyplane1[x * res + y] = h(pos.x, pos.y, pos.z, n, radius, outer_radius);
            }
        }

        tesselate_adjacent_xy_plane_pair(
            box_count,
            xyplane0, xyplane1,
            z - 1,
            triangles,
            isovalue,
            grid_min, grid_max, res,
            grid_min, grid_max, res,
            grid_min, grid_max, res);

        xyplane1.swap(xyplane0);
    }

    cout << endl;

    if (0 < triangles.size())
        write_triangles_to_binary_stereo_lithography_file(triangles, "out.stl");

    // Print box-counting dimension
    // Make sure that step_size != 1.0f :)
    cout << "Box counting dimension: " << logf(static_cast<float>(box_count)) / logf(1.0f/step_size) << endl;

    return 0;
}

```

[![enter image description here](https://i.sstatic.net/iZYnf.png)](https://i.sstatic.net/iZYnf.png)

The relevant documents are at:

[Procedural generation of genus $k$ tori triangle meshes](https://computergraphics.stackexchange.com/questions/13794/procedural-generation-of-genus-k-tori-triangle-meshes)

and

<https://math.stackexchange.com/questions/152256/implicit-equation-for-double-torus-genus-2-orientable-surface>

and

<https://github.com/sjhalayka/k-torus>

**Tags:** computational-geometry


---

## 1 answers

### Answer by username_0 on 2023-11-11. Score: 2

As you will see in the code, the tori are multiplied together, and a non-zero isovalue is used.

The final code is at: <https://github.com/sjhalayka/k-genus_torus>

[![genus 5 tori](https://i.sstatic.net/r38ND.png)](https://i.sstatic.net/r38ND.png)

[![enter image description here](https://i.sstatic.net/erb2G.png)](https://i.sstatic.net/erb2G.png)

> **Comments:**
> **username_1**: did you use some library to implement that?  
> **username_0**: The code is all open source. I used some of the code from Paul Bourke's website -- https://paulbourke.net/geometry/polygonise/ --, and the rest of the code is mine. No external libraries are needed.  

---

