Generator of evenly spaced points in a circle in p

2019-02-07 05:17发布

问题:

I am tasked with generating evenly (more or less) spaced points on concentric rings of an invisible circle. The function should take a list of radii, and number of points to plot for a given radius as arguments. For example for a radius of 0 it should plot 1 point at (0,0). For a circle of radius of 1, it should plot 10 points along the circumference of the circle, spaced out by an angle of 2pi/10. For a circle of radius 2, 20 points along the circumference, spaced out by an angle of 2pi/20.

The generator should take the following parameters:

n, r_max, m

and should generate rings of coordinate pairs at radii

r_i = i*r_max/n for i = 0,1,..,n.

Each ring should have n*i points uniformly distributed in θ where n_i=1 for i=0; n_i = mi for i>0

When the function is called like this:

for r, t in genpolar.rtuniform(n=10, rmax=0.1, m=6):
      plot(r * cos(t), r * sin(t), 'bo')

it should return a plot that looks like:

Here is what I've come up with so far:

def rtpairs(R, N):
        R=[0.0,0.1,0.2]
        N=[1,10,20]
        r=[]
        t=[]
        for i in N:
                theta=2*np.pi/i
            t.append(theta)

        for j in R:
            j=j
            r.append(j)

    plt.plot(r*np.cos(t),r*np.sin(t), 'bo')
    plt.show()

but I'm pretty sure there is a more efficient method using two for loops.

Many thanks

回答1:

I figured it out. The code goes like this:

import numpy as np
import matplotlib.pyplot as plt

T = [1, 10, 20, 30, 40, 50, 60]
R = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6]



def rtpairs(r, n):

    for i in range(len(r)):
       for j in range(n[i]):    
        yield r[i], j*(2 * np.pi / n[i])

for r, t in rtpairs(R, T):
    plt.plot(r * np.cos(t), r * np.sin(t), 'bo')
plt.show()


回答2:

Here is one way to do this.

import numpy as np
import matplotlib.pyplot as plt

def circle_points(r, n):
    circles = []
    for r, n in zip(r, n):
        t = np.linspace(0, two_pi, n)
        x = r * np.cos(t)
        y = r * np.sin(t)
        circles.append(np.c_[x, y])
    return circles

When you pass this function in the appropriate lists, one with the radius for each circle and the other with the desired number of points it returns a list of coordinate arrays, one for each circle.

r = [0, 0.1, 0.2]
n = [1, 10, 20]
circles = circle_points(r, n)

These can be plotted as follows.

fig, ax = plt.subplots()
for circle in circles:
    ax.scatter(circle[:, 0], circle[:, 1])
ax.set_aspect('equal')
plt.show()

Here we see the result for more circles.

n = [1, 10, 20, 30, 40, 50, 60]
r = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6]
circles = circle_points(r, n)

fig, ax = plt.subplots()
for circle in circles:
    ax.scatter(circle[:, 0], circle[:, 1])
ax.set_aspect('equal')
plt.show()



回答3:

I don't know python but this formula should help.

int ringNumber = 0

int n = ringNumber-1

((n/n+1)*60)-60 = degrees between points(except for ring zero, which the point is the center



回答4:

You do have to cycle through the entire circle for all radii, so your plot call is pretty much stuck with some M*N process.

The code details can be slightly improved. For starters, your R list already holds the values you want; there's no need to construct a new list with the same values. You can build the t list with a straightforward list comprehension.

Is this what you wanted?

    N=[1,10,20]
    t = [2*np.pi/i for i in N]
    for R in N:
        plt.plot(R*np.cos(t),R*np.sin(t), 'bo')

    plt.show()