2016-10-04 237 views
0

我找到了this answer,這似乎與這個問題有些相關,但是我想知道是否可以一個接一個地生成座標而沒有額外的〜22%( 1 - π/ 4)將每個點與圓的半徑進行比較的損失(通過計算圓的中心與該點之間的距離)。在網格中生成座標在一個圓內的座標

到目前爲止,我在Python中有以下功能。我知道Gauss' circle problem號碼座標我會結束,但我想要一個一個地產生這些點。

from typing import Iterable 
from math import sqrt, floor 

def circCoord(sigma: float =1.0, centroid: tuple =(0, 0)) -> Iterable[tuple]: 
    r""" Generate all coords within $3\vec{\sigma}$ of the centroid """ 

    # The number of least iterations is given by Gauss' circle problem: 
    # http://mathworld.wolfram.com/GausssCircleProblem.html 

    maxiterations = 1 + 4 * floor(3 * sigma) + 4 * sum(\ 
     floor(sqrt(9 * sigma**2 - i**2)) for i in range(1, floor(3 * sigma) + 1) 
    ) 

    for it in range(maxiterations): 
     # `yield` points in image about `centroid` over which we loop 

我試圖做的是遍歷只有那些(在上面的功能在centroid)趴在3 *西格瑪像素的像素。


我寫了下面的示例腳本,證明下面的解決方案是準確的。

#! /usr/bin/env python3 
# -*- coding: utf-8 -*- 


import matplotlib.pyplot as plt 
from matplotlib.patches import Ellipse 
import numpy as np 
import argparse 
from typing import List, Tuple 
from math import sqrt 


def collect(x: int, y: int, sigma: float =3.0) -> List[Tuple[int, int]]: 
    """ create a small collection of points in a neighborhood of some point 
    """ 
    neighborhood = [] 

    X = int(sigma) 
    for i in range(-X, X + 1): 
     Y = int(pow(sigma * sigma - i * i, 1/2)) 
     for j in range(-Y, Y + 1): 
      neighborhood.append((x + i, y + j)) 

    return neighborhood 


def plotter(sigma: float =3.0) -> None: 
    """ Plot a binary image """  
    arr = np.zeros([sigma * 2 + 1] * 2) 

    points = collect(int(sigma), int(sigma), sigma) 

    # flip pixel value if it lies inside (or on) the circle 
    for p in points: 
     arr[p] = 1 

    # plot ellipse on top of boxes to show their centroids lie inside 
    circ = Ellipse(\ 
     xy=(int(sigma), int(sigma)), 
     width=2 * sigma, 
     height=2 * sigma, 
     angle=0.0 
    ) 

    fig = plt.figure(0) 
    ax = fig.add_subplot(111, aspect='equal') 
    ax.add_artist(circ) 
    circ.set_clip_box(ax.bbox) 
    circ.set_alpha(0.2) 
    circ.set_facecolor((1, 1, 1)) 
    ax.set_xlim(-0.5, 2 * sigma + 0.5) 
    ax.set_ylim(-0.5, 2 * sigma + 0.5) 

    plt.scatter(*zip(*points), marker='.', color='white') 

    # now plot the array that's been created 
    plt.imshow(-arr, interpolation='none', cmap='gray') 
    #plt.colorbar() 

    plt.show() 


if __name__ == '__main__': 
    parser = argparse.ArgumentParser() 

    parser.add_argument('-s', '--sigma', type=int, \ 
     help='Circle about which to collect points' 
    ) 

    args = parser.parse_args() 

    plotter(args.sigma) 

而且輸出

./circleCheck.py -s 4 

是:

enter image description here

回答

1

什麼只是這樣的事情(對於圓形的原點)?

X = int(R) # R is the radius 
for x in range(-X,X+1): 
    Y = int((R*R-x*x)**0.5) # bound for y given x 
    for y in range(-Y,Y+1): 
     yield (x,y) 

這可以很容易地適應一般情況下,當圓不是在原點居中。

+0

這看起來更好,因爲它不是浪費。 – bjd2385

+0

我已經在上面添加了一個小測試腳本,這也使得一個很好的視覺'確認'情節。 – bjd2385

0

你可能要考慮我的高斯圓問題的算法(與一些Java源代碼和一個醜陋的,但方便的插圖):https://stackoverflow.com/a/42373448/5298879

這比在宿舍的一個計時點快周圍3.4倍,再加上中心,再加上軸上的,你現在正在做的,而只是多一行代碼。

你只是想象一個題寫的正方形,並且只計算該圓圈內那個正方形之外的東西的八分之一。