2012-01-25 10 views
10

के साथ एक आयताकार परिधि पर एक यादृच्छिक बिंदु उत्पन्न करें किसी भी विशेष आयताकार (x1, y1) - (x2, y2) को देखते हुए, मैं इसके परिधि पर एक यादृच्छिक बिंदु कैसे उत्पन्न कर सकता हूं?वर्दी वितरण

मैं कुछ दृष्टिकोणों के साथ आया हूं, लेकिन ऐसा लगता है कि ऐसा करने के लिए एक सुंदर कैनोनिकल तरीका होना चाहिए।

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

+1

मुझे लगता है कि चाहते हैं कि धारणात्मक, कैसे आप वास्तव में इसे लागू किया पर ध्यान दिए बिना, "खुलासा" दृष्टिकोण सबसे अच्छा होगा। – Lazarus

+2

आपका अंतिम विचार अच्छा लगता है। यही वह है जो मैं करता हूं। – yurib

+0

मुझे लगता है कि यह http://math.stackexchange.com/ में है; लेकिन आपका तीसरा दृष्टिकोण ठोस लगता है। – ANeves

उत्तर

14

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

+0

उत्कृष्ट विचार फिर से: पक्षों को चुनने की संभावना। –

2

आपका अंतिम सुझाव मेरे लिए सबसे अच्छा लगता है।

परिधि को एक लंबी लाइन [लम्बाई 2*a + 2*b] के रूप में देखें, इसके भीतर एक यादृच्छिक संख्या उत्पन्न करें, गणना करें कि बिंदु आयत पर कहां है [मान लीजिए कि यह कुछ मनमानी बिंदु से शुरू होता है, इससे कोई फर्क नहीं पड़ता] ।

इसे केवल एक यादृच्छिक की आवश्यकता है और इस प्रकार अपेक्षाकृत सस्ता है [यादृच्छिक कभी-कभी महंगा संचालन होते हैं]।

यह भी समान है, और यह साबित करने के लिए तुच्छ है, यादृच्छिक कार्य प्रत्येक बिंदु पर आपको प्राप्त करने का एक मौका भी है [मान लीजिए कि यादृच्छिक कार्य एक समान है)।

3

यदि परिधि पर 'यादृच्छिक बिंदु' से आप वास्तव में 'परिधि की लंबाई से एक समान यादृच्छिक वितरण से चयनित बिंदु' का मतलब करते हैं, तो हां, आपका 'खुलासा' दृष्टिकोण सही है।

यह उल्लेख किया जाना चाहिए कि आपके पिछले दृष्टिकोण को एक परिधीय वितरण के साथ 'परिधि पर यादृच्छिक बिंदु' के रूप में अर्हता प्राप्त करते हैं।

+0

+1 "यादृच्छिक" और "समान रूप से वितरित" के बीच के अंतर को इंगित करने के लिए +1। –

1

उदाहरण के लिए:

static Random random = new Random(); 

/** returns a point (x,y) uniformly distributed 
    * in the border of the rectangle 0<=x<=a, 0<=y<=b 
    */ 
public static Point2D.Double randomRect(double a, double b) { 
    double x = random.nextDouble() * (2 * a + 2 * b); 
    if (x < a) 
     return new Point2D.Double(x, 0); 
    x -= a; 
    if (x < b) 
     return new Point2D.Double(a, x); 
    x -= b; 
    if (x < a) 
     return new Point2D.Double(x, b); 
    else 
     return new Point2D.Double(0, x-a); 
} 
4
यहाँ

, यह नहीं है कि यह :)

//randomness macro 
#define frandom (float)arc4random()/UINT64_C(0x100000000) 
#define frandom_range(low,high) ((high-low)*frandom)+low 

//this will pick a random point on the rect edge 
- (CGPoint)pickPointOnRectEdge:(CGRect)edge { 
    CGPoint pick = CGPointMake(edge.origin.x, edge.origin.y); 
    CGFloat a = edge.size.height; 
    CGFloat b = edge.size.width; 
    CGFloat edgeLength = 2*a + 2*b; 

    float randomEdgeLength = frandom_range(0.0f, (float)edgeLength); 

    //going from bottom left counter-clockwise 
    if (randomEdgeLength<a) { 
    //left side a1 
    pick = CGPointMake(edge.origin.x, edge.origin.y + a); 
    } else if (randomEdgeLength < a+b) { 
    //top side b1 
    pick = CGPointMake(edge.origin.x + randomEdgeLength - a, edge.origin.y + edge.size.height); 
    } else if (randomEdgeLength < (a + b) + a) { 
    //right side a2 
    pick = CGPointMake(edge.origin.x + edge.size.width, edge.origin.y + randomEdgeLength - (a+b)); 
    } else { 
    //bottom side b2 
    pick = CGPointMake(edge.origin.x + randomEdgeLength - (a + b + a), edge.origin.y); 
    } 
    return pick; 
} 
1

यहाँ मानता समान वितरण के साथ अपने कार्यान्वयन (है उद्देश्य-सी में खुलासा विचार है, काम करने के लिए लगता है x1 < x2 और y1 < y2):

void randomPointsOnPerimeter(int x1, int y1, int x2, int y2) { 
    int width = abs(x2 - x1); 
    int height = abs(y2 - y1); 
    int perimeter = (width * 2) + (height * 2); 

    // number of points proportional to perimeter 
    int n = (int)(perimeter/8.0f); 

    for (int i = 0; i < n; i++) { 
     int x, y; 
     int dist = rand() % perimeter; 

     if (dist <= width) { 
      x = (rand() % width) + x1; 
      y = y1; 
     } else if (dist <= width + height) { 
      x = x2; 
      y = (rand() % height) + y1; 
     } else if (dist <= (width * 2) + height) { 
      x = (rand() % width) + x1; 
      y = y2; 
     } else { 
      x = x1; 
      y = (rand() % height) + y1; 
     } 

     // do something with (x, y)... 

    } 
} 
0

यहाँ Javascri में मेरी कार्यान्वयन है pt

 function pickPointOnRectEdge(width,height){ 
      var randomPoint = Math.random() * (width * 2 + height * 2); 
      if (randomPoint > 0 && randomPoint < height){ 
       return { 
        x: 0, 
        y: height - randomPoint 
       } 
      } 
      else if (randomPoint > height && randomPoint < (height + width)){ 
       return { 
        x: randomPoint - height, 
        y: 0 
       } 
      } 
      else if (randomPoint > (height + width) && randomPoint < (height * 2 + width)){ 
       return { 
        x: width, 
        y: randomPoint - (width + height) 
       } 
      } 
      else { 
       return { 
        x: width - (randomPoint - (height * 2 + width)), 
        y: height 
       } 
      } 
     } 
0

लगा कि मैं शाखाओं के बिना ऐसा करने के लिए, यादृच्छिक संख्या है कि "सामने आया" आयत चलता है के एक समारोह के रूप में दोनों एक्स और वाई coords व्यक्त की कोशिश करेंगे।

X = Blue, Y = Red

जे एस:

function randomOnRect() { 
    let r = Math.random(); 
    return [Math.min(1, Math.max(0, Math.abs((r * 4 - .5) % 4 - 2) - .5)), 
      Math.min(1, Math.max(0, Math.abs((r * 4 + .5) % 4 - 2) - .5))] 
} 
संबंधित मुद्दे