समान रूप से एक बिंदु पर n अंक वितरित करना


121

मुझे एक एल्गोरिथ्म की आवश्यकता है जो मुझे N अंक (20 से कम, शायद) के लिए एक गोले के चारों ओर स्थितियां दे सकती है जो उन्हें अस्पष्ट रूप से फैलाता है। "पूर्णता" की कोई आवश्यकता नहीं है, लेकिन मुझे इसकी आवश्यकता है ताकि उनमें से कोई भी एक साथ गुच्छित न हो।

  • इस प्रश्न ने अच्छा कोड प्रदान किया, लेकिन मुझे यह वर्दी बनाने का कोई तरीका नहीं मिला, क्योंकि यह 100% यादृच्छिक रूप से प्रतीत होता था।
  • इस ब्लॉग पोस्ट की सिफारिश की गई थी कि गोले पर अंकों की संख्या के इनपुट की अनुमति देने के दो तरीके हैं, लेकिन Saff और Kuijlaars एल्गोरिथ्म वास्तव में psuedocode में है जिसे मैं स्थानांतरित कर सकता हूं, और कोड उदाहरण मुझे "नोड [k]" मिला, जो नहीं मिल सका। समझाया और उस संभावना को बर्बाद कर दिया। दूसरा ब्लॉग उदाहरण था गोल्डन सेक्शन सर्पिल, जिसने मुझे अजीब, गुदगुदाने वाले परिणाम दिए, जिसमें निरंतर त्रिज्या को परिभाषित करने का कोई स्पष्ट तरीका नहीं था।
  • इस सवाल से यह एल्गोरिथ्म ऐसा लगता है कि यह संभवतः काम कर सकता है, लेकिन मैं उस पृष्ठ पर एक साथ टुकड़ा नहीं कर सकता जो कि pededocode या कुछ भी है।

कुछ अन्य प्रश्न सूत्र जो मैंने यादृच्छिक रूप से समान वितरण के बारे में बताए थे, जो उस स्तर की जटिलता को जोड़ता है जिसके बारे में मुझे कोई चिंता नहीं है। मैं माफी मांगता हूं कि यह इतना मूर्खतापूर्ण सवाल है, लेकिन मैं यह दिखाना चाहता था कि मैं वास्तव में सख्त दिख रहा हूं और अभी भी कम आया हूं।

इसलिए, जो मैं देख रहा हूं वह एक इकाई क्षेत्र के चारों ओर एन बिंदुओं को समान रूप से वितरित करने के लिए सरल छद्मकोड है, जो या तो गोलाकार या कार्टेशियन निर्देशांक में लौटता है। इससे भी बेहतर अगर यह थोड़ा रैंडमाइजेशन के साथ भी वितरित कर सकता है (एक स्टार के चारों ओर ग्रहों पर विचार करें, शालीनता से फैलता है, लेकिन लीवर के लिए कमरे के साथ)।


आपका क्या मतलब है "यादृच्छिकता के एक बिट के साथ"? क्या आप कुछ अर्थों में गड़बड़ी का मतलब है?
निन्जाएजेको

32
ओपी भ्रमित है। वह जिस चीज की तलाश कर रहा है वह एक गोले पर एन-पॉइंट्स लगाना है, ताकि किसी भी दो बिंदुओं के बीच की न्यूनतम दूरी यथासंभव बड़ी हो। यह पूरे क्षेत्र में "समान रूप से वितरित" होने का रूप देगा। यह एक क्षेत्र पर एक समान यादृच्छिक वितरण बनाने के लिए पूरी तरह से असंबंधित है, जो कि उन लिंक के बारे में बहुत सारे हैं, और नीचे दिए गए कई उत्तरों के बारे में क्या बात कर रहे हैं।
ब्लूराजा - डैनी पफ्लुगुएफ़ट

1
यदि आप उन्हें यादृच्छिक नहीं दिखना चाहते हैं तो 20 से अधिक अंक नहीं हैं।
जॉन एलेक्सियॉ

2
इसे करने का एक तरीका है (इसमें कोड उदाहरण हैं): pdfs.semanticscholar.org/97a6/… (ऐसा लगता है कि यह प्रतिकर्षण बल गणना का उपयोग करता है)
trusktr

1
निश्चित रूप से N पर {4, 6, 8, 12, 20} के मूल्यों के लिए सटीक समाधान मौजूद हैं जिनमें प्रत्येक बिंदु से प्रत्येक (निकटतम) की दूरी सभी बिंदुओं और सभी निकटतम पड़ोसियों के लिए एक निरंतर है।
dmckee --- पूर्व-संचालक बिल्ली का बच्चा

जवाबों:


13

में इस उदाहरण कोड node[k] सिर्फ kth नोड है। आप एक सरणी N अंक उत्पन्न कर रहे हैं और node[k]kth (0 से N-1 तक) है। यदि वह सब आपको भ्रमित कर रहा है, तो उम्मीद है कि अब आप इसका उपयोग कर सकते हैं।

(दूसरे शब्दों में, kआकार N की एक सरणी है जिसे कोड टुकड़ा शुरू होने से पहले परिभाषित किया गया है, और जिसमें अंकों की एक सूची शामिल है)।

वैकल्पिक रूप से , यहां दूसरे उत्तर पर निर्माण (और पायथन का उपयोग करके):

> cat ll.py
from math import asin
nx = 4; ny = 5
for x in range(nx):
    lon = 360 * ((x+0.5) / nx)
    for y in range(ny):                                                         
        midpt = (y+0.5) / ny                                                    
        lat = 180 * asin(2*((y+0.5)/ny-0.5))                                    
        print lon,lat                                                           
> python2.7 ll.py                                                      
45.0 -166.91313924                                                              
45.0 -74.0730322921                                                             
45.0 0.0                                                                        
45.0 74.0730322921                                                              
45.0 166.91313924                                                               
135.0 -166.91313924                                                             
135.0 -74.0730322921                                                            
135.0 0.0                                                                       
135.0 74.0730322921                                                             
135.0 166.91313924                                                              
225.0 -166.91313924                                                             
225.0 -74.0730322921                                                            
225.0 0.0                                                                       
225.0 74.0730322921                                                             
225.0 166.91313924
315.0 -166.91313924
315.0 -74.0730322921
315.0 0.0
315.0 74.0730322921
315.0 166.91313924

यदि आप ऐसा करते हैं, तो आप देखेंगे कि ऊर्ध्वाधर रिक्ति ध्रुवों के पास बड़ी है, ताकि प्रत्येक बिंदु अंतरिक्ष के समान कुल क्षेत्रफल के करीब स्थित हो (ध्रुवों के पास "क्षैतिज रूप से कम जगह" हो, इसलिए यह अधिक "लंबवत" देता है )।

यह उनके पड़ोसियों के लिए समान दूरी के बारे में सभी बिंदुओं के समान नहीं है (जो कि मुझे लगता है कि आपके लिंक के बारे में बात कर रहे हैं), लेकिन यह जो आप चाहते हैं उसके लिए पर्याप्त हो सकता है और बस एक समान लेट / लोन ग्रिड बनाने में सुधार करता है। ।


अच्छा है, गणितीय समाधान देखना अच्छा है। मैं एक हेलिक्स और चाप लंबाई जुदाई का उपयोग करने के बारे में सोच रहा था। मैं अभी भी निश्चित नहीं हूं कि इष्टतम समाधान कैसे प्राप्त किया जाए जो एक दिलचस्प समस्या है।
रॉबर्ट राजा

क्या आपने देखा कि मैंने शीर्ष पर नोड [k] का स्पष्टीकरण शामिल करने के लिए अपने उत्तर को संपादित किया? मुझे लगता है कि आप सभी की जरूरत हो सकती है ...
andrew Cooke

अद्भुत, स्पष्टीकरण के लिए धन्यवाद। मैं इसे बाद में आज़माऊंगा, क्योंकि मेरे पास वर्तमान में समय नहीं है, लेकिन मेरी मदद करने के लिए बहुत-बहुत धन्यवाद। मैं आपको बताता हूँ कि यह मेरे उद्देश्यों के लिए कैसे काम करता है। ^ ^
बीफ

सर्पिल विधि का उपयोग मेरी आवश्यकताओं को पूरी तरह से फिट बैठता है, मदद और स्पष्टीकरण के लिए बहुत बहुत धन्यवाद। :)
fall

13
लिंक मृत लगता है।
Scheintod

140

फिबोनाची क्षेत्र एल्गोरिथ्म इसके लिए बहुत अच्छा है। यह तेज़ है और परिणाम देता है कि एक नज़र में आसानी से मानव आँख को मूर्ख बना देगा। आप प्रसंस्करण के साथ किया गया एक उदाहरण देख सकते हैं जो समय के साथ परिणाम दिखाएगा जैसे अंक जोड़े जाते हैं। यहाँ @gman द्वारा बनाया गया एक और शानदार इंटरैक्टिव उदाहरण है। और यहाँ अजगर में एक सरल कार्यान्वयन है।

import math


def fibonacci_sphere(samples=1):

    points = []
    phi = math.pi * (3. - math.sqrt(5.))  # golden angle in radians

    for i in range(samples):
        y = 1 - (i / float(samples - 1)) * 2  # y goes from 1 to -1
        radius = math.sqrt(1 - y * y)  # radius at y

        theta = phi * i  # golden angle increment

        x = math.cos(theta) * radius
        z = math.sin(theta) * radius

        points.append((x, y, z))

    return points

1000 नमूने आपको यह देते हैं:

यहां छवि विवरण दर्ज करें


phi को परिभाषित करते समय एक चर n कहा जाता है: phi = ((i + rnd)% n) * वेतन वृद्धि। N = नमूने है?
एंड्रयू स्टैरॉसिक

@AndrewStaroscik हाँ! जब मैंने पहली बार कोड का उपयोग किया था तो मैंने "n" को एक चर के रूप में इस्तेमाल किया और बाद में नाम बदल दिया लेकिन परिश्रम नहीं किया। उस पकड़ने के लिए धन्यवाद!
Fnord


4
@ Xarbrough कोड आपको एक इकाई क्षेत्र के आसपास अंक देता है, इसलिए आप त्रिज्या के लिए जो भी स्केलर चाहते हैं, उसके द्वारा प्रत्येक बिंदु को गुणा करें।
Fnord

2
@ शब्द: क्या हम उच्च आयामों के लिए ऐसा कर सकते हैं?
पिकाचुशमेलेऑन

108

स्वर्ण सर्पिल विधि

आपने कहा कि आप काम करने के लिए सुनहरा सर्पिल विधि नहीं प्राप्त कर सकते हैं और यह शर्म की बात है क्योंकि यह वास्तव में, वास्तव में अच्छा है। मैं आपको इसके बारे में पूरी जानकारी देना चाहूंगा ताकि शायद आप समझ सकें कि इसे किस तरह से दूर रखा जा सकता है।

तो यहाँ एक जाली बनाने का एक तेज़, गैर-यादृच्छिक तरीका है जो लगभग सही है; जैसा कि ऊपर चर्चा की गई है, कोई जाली सही नहीं होगी, लेकिन यह काफी अच्छा हो सकता है। यह BendWavy.org पर अन्य तरीकों की तुलना में है, लेकिन यह सिर्फ एक अच्छा और सुंदर लग रहा है और साथ ही सीमा में रिक्ति के बारे में भी गारंटी है।

प्राइमर: यूनिट डिस्क पर सूरजमुखी के सर्पिल

इस एल्गोरिथ्म को समझने के लिए, मैं पहली बार आपको 2 डी सूरजमुखी सर्पिल एल्गोरिथ्म को देखने के लिए आमंत्रित करता हूं। यह इस तथ्य पर आधारित है कि सबसे अपरिमेय संख्या सुनहरा अनुपात है (1 + sqrt(5))/2और यदि कोई व्यक्ति "केंद्र पर खड़ा हो," पूरे मोड़ का एक सुनहरा अनुपात मोड़ता है, तो उस दिशा में एक और बिंदु उत्सर्जित करता है, "स्वाभाविक रूप से एक का निर्माण करता है" सर्पिल जो, जैसा कि आप अधिक से अधिक संख्या में अंक प्राप्त करते हैं, फिर भी अच्छी तरह से परिभाषित 'बार' होने से इंकार करते हैं जो अंक रेखा पर चलते हैं। (नोट 1।)

डिस्क पर रिक्ति के लिए एल्गोरिथ्म है,

from numpy import pi, cos, sin, sqrt, arange
import matplotlib.pyplot as pp

num_pts = 100
indices = arange(0, num_pts, dtype=float) + 0.5

r = sqrt(indices/num_pts)
theta = pi * (1 + 5**0.5) * indices

pp.scatter(r*cos(theta), r*sin(theta))
pp.show()

और यह ऐसे परिणाम पैदा करता है जो दिखते हैं (n = 100 और n = 1000):

यहां छवि विवरण दर्ज करें

बिंदुओं को रेडियल रूप से फैलाएं

अहम अजीब बात सूत्र है r = sqrt(indices / num_pts) ; मैं उस एक के पास कैसे आया? (नोट 2।)

ठीक है, मैं यहाँ वर्गमूल का उपयोग कर रहा हूँ क्योंकि मैं चाहता हूँ कि ये डिस्क के चारों ओर सम-क्षेत्र रिक्ति हो। यही कारण है कि कह रही है कि बड़े की सीमा में रूप में ही है एन मैं एक छोटे से क्षेत्र चाहते आर ∈ ( आर , आर + डी आर ), Θ ∈ ( θ , θ + d θ ) ने अपने क्षेत्र के लिए आनुपातिक अंकों की संख्या को रोकने के लिए, जो है आर डी आर डी θ । अब यदि हम दिखावा करते हैं कि हम यहां एक यादृच्छिक चर के बारे में बात कर रहे हैं, तो इसकी सीधी व्याख्या यह है कि संयुक्त संभावना घनत्व ( R , Θ ) के लिए केवल cr हैकुछ निरंतर सी के लिए । इकाई डिस्क पर सामान्यीकरण फिर c = 1 / disk को बल देगा ।

अब मैं एक चाल शुरू करता हूँ। यह प्रायिकता सिद्धांत से आता है, जहां इसे प्रतिलोम सीडीएफ के नमूने के रूप में जाना जाता है : मान लीजिए कि आप एक संभाव्यता घनत्व f ( z ) के साथ एक यादृच्छिक चर उत्पन्न करना चाहते थे और आपके पास एक यादृच्छिक चर U ~ यूनिफ़ॉर्म (0, 1) है, जैसे बाहर आता है अधिकांश प्रोग्रामिंग भाषाओं में। आप यह कैसे करते हैं?random()

  1. सबसे पहले, अपने घनत्व को एक संचयी वितरण फ़ंक्शन या सीडीएफ में बदल दें, जिसे हम एफ ( जेड ) कहेंगे । सीडीएफ, याद रखें, व्युत्पन्न च के साथ 0 से 1 तक एकतरफा बढ़ता है ( जेड ) के ।
  2. फिर सीडीएफ के व्युत्क्रम फ़ंक्शन F -1 ( z) की गणना करें ) ।
  3. आप पाएंगे कि Z = F -1 ( U ) लक्ष्य घनत्व के अनुसार वितरित किया गया है। (नोट 3)।

अब सुनहरे अनुपात सर्पिल चाल रिक्त स्थान एक अच्छी तरह से भी पैटर्न में बाहर अंक के लिए θ तो चलो कि बाहर एकीकृत करते हैं; यूनिट डिस्क के लिए हमें F ( r ) = r 2 के साथ छोड़ दिया जाता है । तो उलटा फ़ंक्शन एफ -1 ( यू ) = यू 1/2 है , और इसलिए हम ध्रुवीय निर्देशांक में डिस्क पर यादृच्छिक अंक उत्पन्न करेंगे r = sqrt(random()); theta = 2 * pi * random()

अब इस व्युत्क्रम फ़ंक्शन को बेतरतीब ढंग से नमूना लेने के बजाय हम इसे समान रूप से नमूना कर रहे हैं , और वर्दी नमूने के बारे में अच्छी बात यह है कि बड़े एन की सीमा में अंक कैसे फैलते हैं, के बारे में हमारे परिणाम ऐसा व्यवहार करेंगे जैसे हमने यादृच्छिक रूप से नमूना लिया था। यह संयोजन चाल है। इसके बजाय random()हम उपयोग करते हैं (arange(0, num_pts, dtype=float) + 0.5)/num_pts, इसलिए, कहते हैं, अगर हम 10 अंक का नमूना चाहते हैं तो वे हैं r = 0.05, 0.15, 0.25, ... 0.95। हम समान रूप से नमूना आर रिक्ति प्राप्त करने के लिए करते हैं, और हम आउटपुट में भयानक "बार" से बचने के लिए सूरजमुखी की वृद्धि का उपयोग करते हैं।

अब एक गोले पर सूरजमुखी कर रहे हैं

बिंदुओं के साथ गोले को बनाने के लिए हमें जो परिवर्तन करने की आवश्यकता है, उसमें केवल गोलाकार निर्देशांक के लिए ध्रुवीय निर्देशांक को स्विच करना शामिल है। बेशक रेडियल समन्वय इस में प्रवेश नहीं करता है क्योंकि हम एक इकाई क्षेत्र पर हैं। चीजें एक छोटे से अधिक सुसंगत यहाँ रखने के लिए, भले ही मैं एक भौतिक विज्ञानी मैं गणितज्ञों 'निर्देशांकों जहां 0 ≤ इस्तेमाल करेंगे के रूप में प्रशिक्षित किया गया था φ ≤ π है अक्षांश ध्रुव और 0 ≤ से नीचे आ रहा है θ ≤ 2π है देशांतर। तो ऊपर से अंतर यह है कि हम मूल रूप से चर स्थान ले रही हैं आर के साथ φ

हमारे क्षेत्र तत्व है, जो था आर डी आर डी θ , अब नहीं-बहुत अधिक जटिल पाप (हो जाता है φ ) घ φθ । तो वर्दी रिक्ति के लिए हमारे संयुक्त घनत्व पाप (है φ ) / 4π। बाहर का घालमेल θ , हम पाते हैं ( φ ) = पाप ( φ ) / 2, इस प्रकार एफ ( φ -) = (क्योंकि (1 φ / 2))। इस Inverting हम कर सकते हैं कि एक समान यादृच्छिक चर acos कैसा दिखेगा (1 - 2 यू ), लेकिन हम समान रूप से बेतरतीब ढंग से करने के बजाय नमूना है, तो हम बजाय का उपयोग φ कश्मीर = acos (1 - 2 ( k+ 0.5) / एन )। और बाकी एल्गोरिथ्म सिर्फ x, y और z निर्देशांक पर इसे पेश कर रहा है:

from numpy import pi, cos, sin, arccos, arange
import mpl_toolkits.mplot3d
import matplotlib.pyplot as pp

num_pts = 1000
indices = arange(0, num_pts, dtype=float) + 0.5

phi = arccos(1 - 2*indices/num_pts)
theta = pi * (1 + 5**0.5) * indices

x, y, z = cos(theta) * sin(phi), sin(theta) * sin(phi), cos(phi);

pp.figure().add_subplot(111, projection='3d').scatter(x, y, z);
pp.show()

फिर से n = 100 और n = 1000 के परिणाम जैसे दिखते हैं: यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें

आगे का अन्वेषण

मैं मार्टिन रॉबर्ट्स के ब्लॉग पर एक चिल्लाहट देना चाहता था। ध्यान दें कि ऊपर मैंने प्रत्येक सूचकांक में 0.5 जोड़कर अपने सूचकांकों की भरपाई की। यह सिर्फ मुझे दृष्टिगत रूप से आकर्षित कर रहा था, लेकिन यह पता चला है कि ऑफसेट की पसंद बहुत मायने रखती है और अंतराल पर स्थिर नहीं है और इसका मतलब पैकिंग में 8% बेहतर सटीकता प्राप्त कर सकती है यदि इसे सही ढंग से चुना जाए। उसका R 2 अनुक्रम प्राप्त करने का एक तरीका भी होना चाहिएएक क्षेत्र को कवर और यह देखना दिलचस्प होगा कि क्या यह एक अच्छा कवर भी उत्पन्न करता है, शायद जैसा है, लेकिन शायद केवल आधे हिस्से से लिया गया इकाई वर्ग तिरछे या तो काट दिया और एक चक्र पाने के लिए चारों ओर फैला दिया।

टिप्पणियाँ

  1. उन "बार" को एक संख्या के लिए परिमेय सन्निकटन द्वारा बनाया जाता है, और एक संख्या के लिए सर्वश्रेष्ठ परिमेय सन्निकटन इसके निरंतर अंश अभिव्यक्ति से आते हैं, z + 1/(n_1 + 1/(n_2 + 1/(n_3 + ...)))जहां zएक पूर्णांक है और n_1, n_2, n_3, ...सकारात्मक पूर्णांकों का एक परिमित या अनंत अनुक्रम है:

    def continued_fraction(r):
        while r != 0:
            n = floor(r)
            yield n
            r = 1/(r - n)

    चूंकि अंश भाग 1/(...)हमेशा शून्य और एक के बीच होता है, निरंतर अंश में एक बड़ा पूर्णांक एक विशेष रूप से अच्छे परिमेय सन्निकटन के लिए अनुमति देता है: "100 और 101 के बीच किसी चीज से विभाजित" "1 और 2. के बीच किसी चीज से विभाजित" से बेहतर है। सबसे तर्कहीन संख्या इसलिए एक है जो कि है 1 + 1/(1 + 1/(1 + ...))और विशेष रूप से अच्छा तर्कसंगत अनुमान नहीं है; एक हल कर सकते हैं φ = 1 + 1 / φ द्वारा के माध्यम से गुणा करके φ सुनहरे अनुपात के लिए सूत्र मिलता है।

  2. उन लोगों के लिए जो NumPy से परिचित नहीं हैं - सभी कार्य "सदिश" हैं, इसलिए यह sqrt(array)वही है जो अन्य भाषाएं लिखती हैं map(sqrt, array)। तो यह एक घटक-द्वारा-घटक sqrtअनुप्रयोग है। एक स्केलर के साथ विभाजन के लिए भी समान है या स्केलर के साथ जोड़ - वे समानांतर में सभी घटकों पर लागू होते हैं।

  3. एक बार जब आप जानते हैं कि यह परिणाम है तो प्रमाण सरल है। यदि आप पूछते हैं कि क्या संभावना है जो z < Z < z + d z है , तो यह वही है जो यह पूछ रहा है कि क्या संभावना है कि z < F -1 ( U ) < z + d z , सभी तीन अभिव्यक्तियों पर F को लागू करें, यह देखते हुए कि यह है एक नीरस रूप से बढ़ता हुआ कार्य, इसलिए F ( z ) < U < F ( z + d z ), F ( z ) + f खोजने के लिए दाहिने हाथ की ओर का विस्तार करें। (z ) d z , और चूंकि U एकसमान है, यह संभावना केवल f ( z ) d z है जैसा कि वादा किया गया है।


4
मुझे यकीन नहीं है कि यह इतना नीचे क्यों है, ऐसा करने के लिए यह अब तक का सबसे अच्छा तेज़ तरीका है।
whn

2
@snb आपको दयालु शब्दों के लिए धन्यवाद! यह भाग में बहुत नीचे है क्योंकि यह बहुत है, बाकी सभी उत्तरों की तुलना में बहुत छोटा है। मुझे आश्चर्य है कि यह भी कर रहा है जैसा कि यह किया गया है।
सीआर ड्रॉस्ट

एक प्रश्न जो मेरे लिए बना हुआ है वह है: किसी भी दो बिंदुओं के बीच दिए गए अधिकतम दूरी के लिए कितने अंक n को वितरित करने की आवश्यकता है?
फेलिक्स डी।

1
@FelixD। यह एक प्रश्न की तरह लगता है जो बहुत तेजी से बहुत जटिल हो सकता है खासकर अगर आप यूक्लिडियन दूरी के बजाय महान-सर्कल दूरी का उपयोग करना शुरू करते हैं। लेकिन शायद मैं एक साधारण प्रश्न का उत्तर दे सकता हूं, अगर कोई अपने वोरोनोई आरेख में बिंदुओं को धर्मान्तरित करता है, तो प्रत्येक वोरोनोई सेल का वर्णन कर सकता है, जिसका क्षेत्रफल लगभग 4π / N है और कोई इसे एक सर्कल के बजाय एक विशेषता दूरी से बदल सकता है। rhombus की तुलना में, πr² = 4 N / N। फिर आर = 2 / √ (एन)।
CR Drost

2
रैंडमली-यूनिफ़ॉर्म इनपुट के बजाय वास्तव में एकरूपता के साथ नमूना प्रमेय का उपयोग करना उन चीजों में से एक है जो मुझे कहते हैं "ठीक है, क्यों # $% और मैंने ऐसा नहीं सोचा था?" । अच्छा लगा।
dmckee --- पूर्व-मॉडरेटर ने बिल्ली का बच्चा

86

इसे एक क्षेत्र पर पैकिंग बिंदुओं के रूप में जाना जाता है, और कोई (ज्ञात) सामान्य, सही समाधान नहीं है। हालांकि, अपूर्ण समाधान के बहुत सारे हैं। तीन सबसे लोकप्रिय लगते हैं:

  1. एक सिमुलेशन बनाएँ । प्रत्येक बिंदु को एक क्षेत्र के लिए विवश इलेक्ट्रॉन के रूप में मानें, फिर एक निश्चित संख्या में चरणों के लिए एक सिमुलेशन चलाएं। इलेक्ट्रॉनों का प्रतिकर्षण स्वाभाविक रूप से सिस्टम को एक अधिक स्थिर स्थिति में ले जाएगा, जहां अंक एक दूसरे से लगभग उतने ही दूर होते हैं जितना कि वे प्राप्त कर सकते हैं।
  2. हाइपरक्यूब अस्वीकृति । यह फैंसी-साउंडिंग विधि वास्तव में सरल है: आप समान रूप सेn गोले के आसपास के क्यूब के अंदर अंक ( उनमें से बहुत अधिक ) चुनते हैं , फिर गोले के बाहर के बिंदुओं को अस्वीकार करते हैं। शेष बिंदुओं को वैक्टर समझें, और उन्हें सामान्य करें। ये आपके "नमूने" हैं - nउनमें से कुछ विधि (बेतरतीब ढंग से, लालची, आदि) का उपयोग करके चुनें ।
  3. सर्पिल सन्निकटन । आप एक गोले के चारों ओर एक सर्पिल का पता लगाते हैं, और समान रूप से सर्पिल के चारों ओर अंक वितरित करते हैं। गणित में शामिल होने के कारण, ये सिमुलेशन की तुलना में समझने के लिए अधिक जटिल हैं, लेकिन बहुत तेज़ी से (और शायद कम कोड को शामिल करते हुए)। सबसे लोकप्रिय सैफ, एट अल द्वारा प्रतीत होता है ।

एक बहुत इस समस्या के बारे में अधिक जानकारी पाया जा सकता है यहां


मैं उस सर्पिल युक्ति को देख रहा हूँ, जिसे andrew Cooke ने नीचे पोस्ट किया है, हालाँकि, क्या आप कृपया मेरे द्वारा इच्छित अंतर और "समान यादृच्छिक वितरण" के बीच अंतर को स्पष्ट कर सकते हैं? क्या केवल 100% यादृच्छिक बिंदुओं को एक गोले पर रखा गया है ताकि उन्हें समान रूप से रखा जा सके? सहायता के लिए धन्यवाद। :)
बेला

4
@Befall: "यूनिफ़ॉर्म रैंडम डिस्ट्रीब्यूशन" का मतलब है प्रोबिलीबिलिटी -डिस्ट्रीब्यूशन एकसमान होना - इसका मतलब है, जब गोले पर एक रैंडम पॉइंट चुनते हैं, तो हर पॉइंट को चुने जाने की बराबर संभावना होती है। इसका अंकों के अंतिम स्थानिक- विश्लेषण से कोई लेना-देना नहीं है, और इस प्रकार आपके प्रश्न से कोई लेना-देना नहीं है।
ब्लूराजा - डैनी पफ्लुगुएफ़ट

आह, ठीक है, बहुत बहुत धन्यवाद। मेरे सवाल के जवाब के लिए खोज करने से दोनों के लिए जवाब मिल सकता है, और मैं वास्तव में समझ नहीं सका जो मेरे लिए व्यर्थ था।
बीतना

स्पष्ट होने के लिए, हर बिंदु को चुने जाने की शून्य संभावना है। क्षेत्र के धरातल पर किन्हीं दो क्षेत्रों के होने की संभावनाओं का अनुपात सतहों के अनुपात के बराबर है।
AturSams

2
अंतिम लिंक अब मृत है
फेलिक्स डी।

10

आप जो खोज रहे हैं उसे गोलाकार आवरण कहते हैं । गोलाकार कवरिंग समस्या बहुत कठिन है और छोटे अंकों को छोड़कर समाधान अज्ञात हैं। एक बात जो निश्चित रूप से ज्ञात है, वह यह है कि एक गोले पर n अंक दिए गए हैं, हमेशा दूरी के दो बिंदु होते हैंd = (4-csc^2(\pi n/6(n-2)))^(1/2) या निकट के हैं।

यदि आप समान क्षेत्र में समान रूप से वितरित अंक बनाने के लिए एक संभाव्य विधि चाहते हैं, तो यह आसान है: गॉसियन वितरण द्वारा समान रूप से अंतरिक्ष में अंक उत्पन्न करें (यह जावा में बनाया गया है, अन्य भाषाओं के लिए कोड खोजने के लिए मुश्किल नहीं है)। तो 3-आयामी अंतरिक्ष में, आपको कुछ ऐसा चाहिए

Random r = new Random();
double[] p = { r.nextGaussian(), r.nextGaussian(), r.nextGaussian() };

फिर मूल से इसकी दूरी को सामान्य करके क्षेत्र पर बिंदु को प्रोजेक्ट करें

double norm = Math.sqrt( (p[0])^2 + (p[1])^2 + (p[2])^2 ); 
double[] sphereRandomPoint = { p[0]/norm, p[1]/norm, p[2]/norm };

एन आयामों में गाऊसी वितरण गोलाकार रूप से सममित है इसलिए गोला पर प्रक्षेपण एक समान है।

बेशक, इस बात की कोई गारंटी नहीं है कि समान रूप से सृजित अंकों के संग्रह में किसी भी दो बिंदुओं के बीच की दूरी नीचे से बांधी जाएगी, इसलिए आप ऐसी किसी भी स्थिति को लागू करने के लिए अस्वीकृति का उपयोग कर सकते हैं जो आपके पास हो सकती है: शायद यह पूरे संग्रह को बनाने के लिए सबसे अच्छा है और फिर यदि आवश्यक हो तो पूरे संग्रह को अस्वीकार करें। (या अब तक आपके द्वारा बनाए गए पूरे संग्रह को अस्वीकार करने के लिए "शुरुआती अस्वीकृति" का उपयोग करें; बस कुछ बिंदुओं को न रखें और दूसरों को छोड़ दें।) आप dऊपर दिए गए फॉर्मूले का उपयोग कर सकते हैं , कुछ सुस्त कर सकते हैं, बीच की दूरी को निर्धारित करने के लिए। नीचे दिए गए बिंदु जो आप अंकों के एक सेट को अस्वीकार कर देंगे। आपको n चुनें 2 दूरियों की गणना करनी होगी, और अस्वीकृति की संभावना सुस्त पर निर्भर करेगी; यह कहना मुश्किल है कि कैसे, इसलिए प्रासंगिक आंकड़ों के लिए एक महसूस करने के लिए एक सिमुलेशन चलाएं।


न्यूनतम अधिकतम दूरी के भावों के लिए बनाया गया। आपके द्वारा उपयोग किए जाने वाले बिंदुओं की संख्या पर सीमाएं लगाने के लिए उपयोगी है। हालांकि इसके लिए एक आधिकारिक स्रोत का संदर्भ अच्छा होगा।
dmckee --- पूर्व-संचालक बिल्ली का बच्चा

6

यह उत्तर उसी 'सिद्धांत' पर आधारित है जिसे इस उत्तर द्वारा अच्छी तरह से रेखांकित किया गया है

मैं इस उत्तर को इस रूप में जोड़ रहा हूं:
- अन्य विकल्पों में से कोई भी 'एकरूपता' की आवश्यकता 'स्पॉट-ऑन' (या स्पष्ट रूप से-स्पष्ट रूप से ऐसा नहीं है) के अनुरूप है। (मूल रूप से पूछे जाने वाले वितरण व्यवहार की तरह ग्रह को पाने के लिए, मूल रूप से पूछना चाहते थे, आप बस k की परिमित सूची से यादृच्छिक रूप से बनाए गए बिंदुओं को खारिज कर देते हैं (k आइटमों में यादृच्छिक संख्या सूचकांक की गिनती)।) - इसके अलावा। यह बहुत कठिन है कि किसी भी कल्पना के बिना अन्य विकल्पों के बीच अंतर कैसे करें, इसलिए यहां यह विकल्प कैसा दिखता है (नीचे), और इसके साथ चलने वाला रेडी-टू-रन कार्यान्वयन।
- निकटतम अन्य आरोपों ने आपको 'कोणीय अक्ष' द्वारा 'एन' को तय करने के लिए मजबूर किया, बनाम दोनों कोणीय अक्ष मूल्यों (जो कि एन की कम मात्रा में होता है) के सिर्फ 'एन' का एक मूल्य यह जानने के लिए बहुत मुश्किल है कि क्या हो सकता है या क्या नहीं ( जैसे आप '5' अंक चाहते हैं - मजेदार है))

20 पर एन के साथ:

यहां छवि विवरण दर्ज करें
और फिर एन 80 पर: यहां छवि विवरण दर्ज करें


यहां रेडी-टू-रन python3 कोड है, जहां एमुलेशन एक ही स्रोत है: " http://web.archive.org/web/20120421191837/http://www.cgafaq.info/weiki/Evenly_distributed_points_on_sphere " दूसरों द्वारा पाया गया । (मैंने जो प्लॉटिंग शामिल किया है, जो 'मुख्य' के रूप में चलने पर आग लेता है: http://www.scipy.org/Cookbook/Matplotlib/mplot3D )

from math import cos, sin, pi, sqrt

def GetPointsEquiAngularlyDistancedOnSphere(numberOfPoints=45):
    """ each point you get will be of form 'x, y, z'; in cartesian coordinates
        eg. the 'l2 distance' from the origion [0., 0., 0.] for each point will be 1.0 
        ------------
        converted from:  http://web.archive.org/web/20120421191837/http://www.cgafaq.info/wiki/Evenly_distributed_points_on_sphere ) 
    """
    dlong = pi*(3.0-sqrt(5.0))  # ~2.39996323 
    dz   =  2.0/numberOfPoints
    long =  0.0
    z    =  1.0 - dz/2.0
    ptsOnSphere =[]
    for k in range( 0, numberOfPoints): 
        r    = sqrt(1.0-z*z)
        ptNew = (cos(long)*r, sin(long)*r, z)
        ptsOnSphere.append( ptNew )
        z    = z - dz
        long = long + dlong
    return ptsOnSphere

if __name__ == '__main__':                
    ptsOnSphere = GetPointsEquiAngularlyDistancedOnSphere( 80)    

    #toggle True/False to print them
    if( True ):    
        for pt in ptsOnSphere:  print( pt)

    #toggle True/False to plot them
    if(True):
        from numpy import *
        import pylab as p
        import mpl_toolkits.mplot3d.axes3d as p3

        fig=p.figure()
        ax = p3.Axes3D(fig)

        x_s=[];y_s=[]; z_s=[]

        for pt in ptsOnSphere:
            x_s.append( pt[0]); y_s.append( pt[1]); z_s.append( pt[2])

        ax.scatter3D( array( x_s), array( y_s), array( z_s) )                
        ax.set_xlabel('X'); ax.set_ylabel('Y'); ax.set_zlabel('Z')
        p.show()
        #end

कम गिनती (2, 5, 7, 13, आदि में एन) पर परीक्षण किया और 'अच्छा' काम करने लगता है


5

प्रयत्न:

function sphere ( N:float,k:int):Vector3 {
    var inc =  Mathf.PI  * (3 - Mathf.Sqrt(5));
    var off = 2 / N;
    var y = k * off - 1 + (off / 2);
    var r = Mathf.Sqrt(1 - y*y);
    var phi = k * inc;
    return Vector3((Mathf.Cos(phi)*r), y, Mathf.Sin(phi)*r); 
};

उपरोक्त फ़ंक्शन को एन लूप कुल और के लूप वर्तमान पुनरावृत्ति के साथ लूप में चलना चाहिए।

यह एक सूरजमुखी के बीज पैटर्न पर आधारित है, सिवाय इसके कि सूरजमुखी के बीज एक आधा गुंबद में घुमावदार होते हैं, और फिर से एक गोले में बदल जाते हैं।

यहाँ एक तस्वीर है, सिवाय इसके कि मैंने कैमरे को गोले के अंदर आधे रास्ते पर रखा है, इसलिए यह 3 डी के बजाय 2d दिखता है क्योंकि कैमरा सभी बिंदुओं के लिए समान दूरी है। http://3.bp.blogspot.com/-9lbPHLccQHA/USXf88_bvVI/AAAAAAAAADY/j7qhQsSZsA8/s640/sphere.jpg


2

Healpix एक घनिष्ठ संबंधित समस्या को हल करता है (समान क्षेत्र पिक्सेल के साथ गोले को पिक्सलेट करता है):

http://healpix.sourceforge.net/

यह शायद ओवरकिल है, लेकिन शायद इसे देखने के बाद आपको एहसास होगा कि इसमें से कुछ अच्छे गुण आपके लिए दिलचस्प हैं। यह सिर्फ एक फ़ंक्शन से अधिक है जो एक बिंदु क्लाउड को आउटपुट करता है।

मैं इसे फिर से खोजने की कोशिश में यहां उतरा; "हीलिपिक्स" नाम बिल्कुल क्षेत्रों को विकसित नहीं करता है ...


1

अंकों की छोटी संख्या के साथ आप एक सिमुलेशन चला सकते हैं:

from random import random,randint
r = 10
n = 20
best_closest_d = 0
best_points = []
points = [(r,0,0) for i in range(n)]
for simulation in range(10000):
    x = random()*r
    y = random()*r
    z = r-(x**2+y**2)**0.5
    if randint(0,1):
        x = -x
    if randint(0,1):
        y = -y
    if randint(0,1):
        z = -z
    closest_dist = (2*r)**2
    closest_index = None
    for i in range(n):
        for j in range(n):
            if i==j:
                continue
            p1,p2 = points[i],points[j]
            x1,y1,z1 = p1
            x2,y2,z2 = p2
            d = (x1-x2)**2+(y1-y2)**2+(z1-z2)**2
            if d < closest_dist:
                closest_dist = d
                closest_index = i
    if simulation % 100 == 0:
        print simulation,closest_dist
    if closest_dist > best_closest_d:
        best_closest_d = closest_dist
        best_points = points[:]
    points[closest_index]=(x,y,z)


print best_points
>>> best_points
[(9.921692138442777, -9.930808529773849, 4.037839326088124),
 (5.141893371460546, 1.7274947332807744, -4.575674650522637),
 (-4.917695758662436, -1.090127967097737, -4.9629263893193745),
 (3.6164803265540666, 7.004158551438312, -2.1172868271109184),
 (-9.550655088997003, -9.580386054762917, 3.5277052594769422),
 (-0.062238110294250415, 6.803105171979587, 3.1966101417463655),
 (-9.600996012203195, 9.488067284474834, -3.498242301168819),
 (-8.601522086624803, 4.519484132245867, -0.2834204048792728),
 (-1.1198210500791472, -2.2916581379035694, 7.44937337008726),
 (7.981831370440529, 8.539378431788634, 1.6889099589074377),
 (0.513546008372332, -2.974333486904779, -6.981657873262494),
 (-4.13615438946178, -6.707488383678717, 2.1197605651446807),
 (2.2859494919024326, -8.14336582650039, 1.5418694699275672),
 (-7.241410895247996, 9.907335206038226, 2.271647103735541),
 (-9.433349952523232, -7.999106443463781, -2.3682575660694347),
 (3.704772125650199, 1.0526567864085812, 6.148581714099761),
 (-3.5710511242327048, 5.512552040316693, -3.4318468250897647),
 (-7.483466337225052, -1.506434920354559, 2.36641535124918),
 (7.73363824231576, -8.460241422163824, -1.4623228616326003),
 (10, 0, 0)]

मेरा उत्तर सुधार करने के लिए आप closest_index = randchoice (i, j) को closest_index बदलना चाहिए = मैं
रॉबर्ट राजा

1

अपने दो सबसे बड़े कारकों को लें N, अगर N==20दो सबसे बड़े कारक हैं {5,4}, या, अधिक सामान्यतः {a,b}। गणना

dlat  = 180/(a+1)
dlong = 360/(b+1})

अपना पहला बिंदु {90-dlat/2,(dlong/2)-180}, अपने दूसरे स्थान पर {90-dlat/2,(3*dlong/2)-180}, अपने तीसरे स्थान पर रखें {90-dlat/2,(5*dlong/2)-180}, जब तक कि आप एक बार दुनिया के चक्कर न लगा लें, तब तक आप जिस समय के करीब {75,150}जाते हैं {90-3*dlat/2,(dlong/2)-180}

जाहिर है कि मैं इसे गोलाकार पृथ्वी की सतह पर डिग्री में काम कर रहा हूं, सामान्य अनुवाद के लिए +/- से एन / एस या ई / डब्ल्यू के लिए। और स्पष्ट रूप से यह आपको पूरी तरह से गैर-यादृच्छिक वितरण देता है, लेकिन यह एक समान है और अंक एक साथ गुच्छे नहीं हैं।

कुछ हद तक यादृच्छिकता को जोड़ने के लिए, आप 2 सामान्य रूप से वितरित (मतलब 0 और std dev के {dlat / 3, dlong / 3} के रूप में उपयुक्त) उत्पन्न कर सकते हैं और उन्हें अपने समान रूप से वितरित बिंदुओं में जोड़ सकते हैं।


5
यह बहुत अच्छा लगेगा यदि आपने लैट के बजाय पाप (लैट) में काम किया। जैसा कि यह है, आपको डंडों के पास बहुत सारे गुच्छा मिलेंगे।
andrew cooke

1

संपादित करें: यह उस सवाल का जवाब नहीं देता है जो ओपी के कहने का मतलब है, इसे यहां छोड़ देना अगर लोग इसे किसी भी तरह उपयोगी पाते हैं।

हम infinitessimals के साथ संयुक्त संभावना के गुणन नियम का उपयोग करते हैं। यह आपके वांछित परिणाम को प्राप्त करने के लिए कोड की 2 पंक्तियों में परिणाम करता है:

longitude: φ = uniform([0,2pi))
azimuth:   θ = -arcsin(1 - 2*uniform([0,1]))

(निम्नलिखित समन्वय प्रणाली में परिभाषित :)

यहां छवि विवरण दर्ज करें

आपकी भाषा में आमतौर पर एक समान यादृच्छिक संख्या आदिम होती है। अजगर में उदाहरण के लिए आप random.random()रेंज में एक नंबर वापस करने के लिए उपयोग कर सकते हैं [0,1)। सीमा में यादृच्छिक संख्या प्राप्त करने के लिए आप इस संख्या को k से गुणा कर सकते हैं [0,k)। इस प्रकार अजगर में, uniform([0,2pi))मतलब होगा random.random()*2*math.pi


सबूत

अब हम समान रूप से θ असाइन नहीं कर सकते, अन्यथा हम डंडों से टकरा जाते। हम गोलाकार पच्चर के सतह क्षेत्र के लिए आनुपातिक असाइन करना चाहते हैं (इस आरेख में assign वास्तव में abilities है:

यहां छवि विवरण दर्ज करें

भूमध्य रेखा पर एक कोणीय विस्थापन d dis * r के विस्थापन के परिणामस्वरूप होगा। वह विस्थापन एक मनमाने अज़ीमथ ment पर क्या होगा? ठीक है, z- अक्ष से त्रिज्या है r*sin(θ), इसलिए उस "अक्षांश" की प्रतिच्छेदन कील को प्रतिच्छेद करती है dφ * r*sin(θ)। इस प्रकार हम दक्षिण ध्रुव से उत्तर ध्रुव तक के क्षेत्र को एकीकृत करके, उस से नमूने के लिए क्षेत्र के संचयी वितरण की गणना करते हैं ।

यहां छवि विवरण दर्ज करें(जहां सामान = dφ*r)

अब हम इसका नमूना लेने के लिए CDF का विलोम प्राप्त करने का प्रयास करेंगे: http://en.wikipedia.org/wiki/Inverse_transform_sampling

पहले हम अपने लगभग CD-CDF को उसके अधिकतम मूल्य से विभाजित करके सामान्य करते हैं। यह d r और r को रद्द करने का साइड-इफेक्ट है।

azimuthalCDF: cumProb = (sin(θ)+1)/2 from -pi/2 to pi/2

inverseCDF: θ = -sin^(-1)(1 - 2*cumProb)

इस प्रकार:

let x by a random float in range [0,1]
θ = -arcsin(1-2*x)

यह उस विकल्प के बराबर नहीं है जिसे उसने "100% यादृच्छिक" के रूप में त्याग दिया? मेरी समझ यह है कि वह चाहता है कि उन्हें समान रूप से समान वितरण की तुलना में समान रूप से स्थान दिया जाए।
andrew cooke

@ BlueRaja-DannyPflughoeft: हम्म, काफी गोरा। मुझे लगता है कि मैंने इस प्रश्न को ध्यान से नहीं पढ़ा, जितना मुझे होना चाहिए था। मैं इसे यहाँ वैसे भी छोड़ देता हूँ जब अन्य इसे उपयोगी पाते हैं। इस पर ध्यान दिलाने के लिए धन्यवाद।
निंजाजेको

1

या ... 20 अंक रखने के लिए, icosahedronal चेहरे के केंद्रों की गणना करें। 12 बिंदुओं के लिए, आइकोसाहेड्रोन के कोने ढूंढें। 30 बिंदुओं के लिए, आईसीओसहेड्रोन के किनारों का मध्य बिंदु। आप टेट्राहेड्रोन, क्यूब, डोडेकेहेड्रॉन और ऑक्टाहेड्रोन के साथ एक ही काम कर सकते हैं: एक बिंदु का एक छोर, चेहरे के केंद्र पर और दूसरा किनारों के केंद्र पर है। हालाँकि, उन्हें मिश्रित नहीं किया जा सकता है।


एक अच्छा विचार है, लेकिन यह केवल 4, 6, 8, 12, 20, 24 या 30 अंक के लिए काम करता है।
द गाट विथ द हाट

यदि आप धोखा देना चाहते हैं, तो आप चेहरे और लंबवत केंद्र का उपयोग कर सकते हैं। वे सम-स्पंदित नहीं होंगे बल्कि एक सभ्य सन्निकटन होंगे। यह अच्छा है क्योंकि यह नियतात्मक है।
चेसोफर्नेड

0
# create uniform spiral grid
numOfPoints = varargin[0]
vxyz = zeros((numOfPoints,3),dtype=float)
sq0 = 0.00033333333**2
sq2 = 0.9999998**2
sumsq = 2*sq0 + sq2
vxyz[numOfPoints -1] = array([(sqrt(sq0/sumsq)), 
                              (sqrt(sq0/sumsq)), 
                              (-sqrt(sq2/sumsq))])
vxyz[0] = -vxyz[numOfPoints -1] 
phi2 = sqrt(5)*0.5 + 2.5
rootCnt = sqrt(numOfPoints)
prevLongitude = 0
for index in arange(1, (numOfPoints -1), 1, dtype=float):
  zInc = (2*index)/(numOfPoints) -1
  radius = sqrt(1-zInc**2)

  longitude = phi2/(rootCnt*radius)
  longitude = longitude + prevLongitude
  while (longitude > 2*pi): 
    longitude = longitude - 2*pi

  prevLongitude = longitude
  if (longitude > pi):
    longitude = longitude - 2*pi

  latitude = arccos(zInc) - pi/2
  vxyz[index] = array([ (cos(latitude) * cos(longitude)) ,
                        (cos(latitude) * sin(longitude)), 
                        sin(latitude)])

4
यह उपयोगी होगा यदि आपने कुछ पाठ लिखा है जिसमें बताया गया है कि यह क्या करना है, इसलिए ओपी को विश्वास में लेने की ज़रूरत नहीं है कि यह सिर्फ काम करेगा।
6

0

@robert राजा यह एक बहुत अच्छा समाधान है, लेकिन इसमें कुछ मैला कीड़े हैं। मुझे पता है कि इससे मुझे बहुत मदद मिली, इसलिए कभी भी ढिलाई न बरतें। :) यहाँ एक साफ किया संस्करण है ....

from math import pi, asin, sin, degrees
halfpi, twopi = .5 * pi, 2 * pi
sphere_area = lambda R=1.0: 4 * pi * R ** 2

lat_dist = lambda lat, R=1.0: R*(1-sin(lat))

#A = 2*pi*R^2(1-sin(lat))
def sphere_latarea(lat, R=1.0):
    if -halfpi > lat or lat > halfpi:
        raise ValueError("lat must be between -halfpi and halfpi")
    return 2 * pi * R ** 2 * (1-sin(lat))

sphere_lonarea = lambda lon, R=1.0: \
        4 * pi * R ** 2 * lon / twopi

#A = 2*pi*R^2 |sin(lat1)-sin(lat2)| |lon1-lon2|/360
#    = (pi/180)R^2 |sin(lat1)-sin(lat2)| |lon1-lon2|
sphere_rectarea = lambda lat0, lat1, lon0, lon1, R=1.0: \
        (sphere_latarea(lat0, R)-sphere_latarea(lat1, R)) * (lon1-lon0) / twopi


def test_sphere(n_lats=10, n_lons=19, radius=540.0):
    total_area = 0.0
    for i_lons in range(n_lons):
        lon0 = twopi * float(i_lons) / n_lons
        lon1 = twopi * float(i_lons+1) / n_lons
        for i_lats in range(n_lats):
            lat0 = asin(2 * float(i_lats) / n_lats - 1)
            lat1 = asin(2 * float(i_lats+1)/n_lats - 1)
            area = sphere_rectarea(lat0, lat1, lon0, lon1, radius)
            print("{:} {:}: {:9.4f} to  {:9.4f}, {:9.4f} to  {:9.4f} => area {:10.4f}"
                    .format(i_lats, i_lons
                    , degrees(lat0), degrees(lat1)
                    , degrees(lon0), degrees(lon1)
                    , area))
            total_area += area
    print("total_area = {:10.4f} (difference of {:10.4f})"
            .format(total_area, abs(total_area) - sphere_area(radius)))

test_sphere()

-1

यह काम करता है और यह घातक सरल है। जितने चाहें उतने अंक:

    private function moveTweets():void {


        var newScale:Number=Scale(meshes.length,50,500,6,2);
        trace("new scale:"+newScale);


        var l:Number=this.meshes.length;
        var tweetMeshInstance:TweetMesh;
        var destx:Number;
        var desty:Number;
        var destz:Number;
        for (var i:Number=0;i<this.meshes.length;i++){

            tweetMeshInstance=meshes[i];

            var phi:Number = Math.acos( -1 + ( 2 * i ) / l );
            var theta:Number = Math.sqrt( l * Math.PI ) * phi;

            tweetMeshInstance.origX = (sphereRadius+5) * Math.cos( theta ) * Math.sin( phi );
            tweetMeshInstance.origY= (sphereRadius+5) * Math.sin( theta ) * Math.sin( phi );
            tweetMeshInstance.origZ = (sphereRadius+5) * Math.cos( phi );

            destx=sphereRadius * Math.cos( theta ) * Math.sin( phi );
            desty=sphereRadius * Math.sin( theta ) * Math.sin( phi );
            destz=sphereRadius * Math.cos( phi );

            tweetMeshInstance.lookAt(new Vector3D());


            TweenMax.to(tweetMeshInstance, 1, {scaleX:newScale,scaleY:newScale,x:destx,y:desty,z:destz,onUpdate:onLookAtTween, onUpdateParams:[tweetMeshInstance]});

        }

    }
    private function onLookAtTween(theMesh:TweetMesh):void {
        theMesh.lookAt(new Vector3D());
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.