0

I have been trying for around 2 days now to create the 2 half-moons data set in 3 dimensions.

First, I did it in two dimensions, and this link is very helpful for understanding how to plot the data set: Creating a dataset in the form of two half semi circle arcs in python

Then, I decided to try 3 dimensions. The way to do this would be to think of the shape as a tube that is bent, and this tube is composed of a lot of thin disks. In each of these disks, we take a uniform random number of points, which this link is very useful for: Generate a random point within a circle (uniformly)

After this, I need to rotate and translate these disks, but this is what I am stuck on and would appreciate any help. If you are unable to help and provide code or explanation for this, another approach could also be very helpful.

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
jbg05
  • 51
  • 7

1 Answers1

0

Then, I decided to try 3 dimensions. The way to do this would be to think of the shape as a tube that is bent

Seems like you are trying to generate random points inside the volume of a torus (or half a torus). Instead of following your approach (a series of disks), I suggest a different one. First, you need to parameterize the torus.

Then, you need to generate the random distribution of points.

Let's put the pieces together. I'm going to use Plotly as it has an equal aspect ratio for 3d plots. Obviously, you can also apply offsets to the dataset.

import numpy as np

def random_dist_torus(a, c, n_low=1000, n_high=10000):
    """
    Parameters
    c: radius from the center of the hole to the center of the torus
    a: radius of the tube
    n_low: minimum number of points in the volume
    n_high: maximum number of points in the volume
    """
    n = int(np.random.uniform(n_low, n_high))
    # consider a cross section of the torus, which is going
    # to be a circle. The variable r represents the radius
    # of the points in this cross section.
    r = a * np.random.uniform(0, 1, n)
    # u: angular coordinate of the torus. Here I set it
    # to np.pi, so it will generate only half torus
    u = np.pi * np.random.uniform(0, 1, n)
    # v: circumferential coordinate. Consider a cross section
    # of a torus, which is going to be a circle. v represents
    # the angle around this circle.
    v = 2 * np.pi * np.random.uniform(0, 1, n)
    return (
        (c + r * np.cos(v)) * np.cos(u), # x-coordinates
        (c + r * np.cos(v)) * np.sin(u), # y-coordinates
        r * np.sin(v)  # z-coordinates
    )


import plotly.graph_objects as go

x1, y1, z1 = random_dist_torus(2, 4)
x2, y2, z2 = random_dist_torus(2, 4)
fig = go.Figure(
    data=[
        go.Scatter3d(
            x=x1, y=y1, z=z1,
            mode='markers',
            marker=dict(
                size=2,
            )
        ),
        go.Scatter3d(
            x=x2, y=-y2, z=z2,
            mode='markers',
            marker=dict(
                size=2,
            )
        )
    ])
fig.show()

enter image description here

Davide_sd
  • 10,578
  • 3
  • 18
  • 30
  • What do `u`, `v`, and `r` represent? – jbg05 Apr 10 '22 at 11:39
  • I updated the answer (see the comments in the code). Also, you can play with the parameters to fully understand what they achieve. – Davide_sd Apr 10 '22 at 11:46
  • So where do you use the random distribution of points: https://stackoverflow.com/questions/5837572/generate-a-random-point-within-a-circle-uniformly/50746409#50746409 – jbg05 Apr 10 '22 at 12:21
  • You can see that in the code: each point is parameterized by `r, u, v`. These variables uses a random distribution of values (look for `np.random.uniform`). So, in the cross-section plane, each point has a random radius `r` and a random circumferential direction `v`. They also have a random angular position `u` along the torus. – Davide_sd Apr 10 '22 at 16:06
  • How can I make this so that this is like a perfectly cylindrical tube? This torus is very "tall" and is not a perfect cylindrical shape. How can I make it so that it is like a donut (where the cross sections are perfect circles)? – jbg05 Apr 11 '22 at 07:21
  • You can play with the parameters `a` and `c` when calling `random_dist_torus(a, c)`. For example, you can increase `c` (the radius of the torus) and decrease `a` (the radius of the tube). – Davide_sd Apr 11 '22 at 07:39