亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在矩形的邊緣上獲取兩個點

在矩形的邊緣上獲取兩個點

慕容森 2021-08-26 15:07:48
我有一個矩形,想:在一側(任意)上獲得一個隨機點。在一側(除了先前選擇的)隨機點。我最初的方法是為每個可能的邊創建數組。var arr:Array = [[{x:0,y:0},           // Top                  {x:width,y:0}],      //                 [{x:width,y:0},       // Right                  {x:width,y:height}], //                 [{x:width,y:height},  // Bottom                  {x:0,y:height}],     //                 [{x:0,y:height},      // Left                  {x:0,y:0}]];         //然后,我得到了雙方。 rand是一個實例Rand并具有以下方法: .next()它提供一個介于0和之間的隨機數,1 .between(x,y)它返回一個介于x和之間的隨機數y。var firstSide:Array = arr[rand.next() * arr.length];var secondSide:Array;do {    secondSide = arr[rand.next() * arr.length];} while(secondSide.equals(firstSide));最后,我計算我的分數。var pointOnFirstSide:Object = {x:rand.between(firstSide[0].x, firstSide[1].x),                               y:rand.between(firstSide[0].y, firstSide[1].y};var pointOnSecondSide:Object = {x:rand.between(secondSide[0].x, secondSide[1].x),                                y:rand.between(secondSide[0].y, secondSide[1].y};我認為這不是解決此問題的最有效方法。你會怎么做?
查看完整描述

2 回答

?
慕慕森

TA貢獻1856條經驗 獲得超17個贊

jcalz 已經給出了很好的答案。這是我在評論中詢問的變體的替代版本:當您希望在周長的兩側均勻選擇您的點時,如果您的w : h比率為4 : 1,則第一個點位于水平邊的可能性是 的四倍作為一個垂直的。(這意味著擊中兩個相反的長邊的幾率是 24/45;兩個相反的短邊的幾率是 1/45;并且每個擊中一個的幾率是 20/45——通過一個簡單但略顯乏味的計算。)


const rand = {

  next: () => Math. random (),

  between: (lo, hi) => lo + (hi - lo) * Math .random (),

}


const vertices = (w, h) => [ {x: 0, y: h}, {x: w, y: h}, {x: w, y: 0}, {x: 0, y: 0} ]


const edges = ([v1, v2, v3, v4]) => [ [v1, v2], [v2, v3], [v3, v4], [v4, v1] ]


const randomPoint = ([v1, v2], rand) => ({

  x: v1 .x + rand .next () * (v2 .x - v1 .x),

  y: v1 .y + rand .next () * (v2 .y - v1 .y),

})


const getIndex = (w, h, x) => x < w ? 0 : x < w + h ? 1 : x < w + h + w ? 2 : 3


const twoPoints = (w, h, rand) => {

  const es = edges (vertices (w, h) )

  const perimeter = 2 * w + 2 * h

  const r1 = rand .between (0, perimeter)

  const idx1 = getIndex (w, h, r1)

  const r2 = (

    rand. between (0, perimeter - (idx1 % 2 == 0 ? w : h)) +

      Math .ceil ((idx1 + 1) / 2) * w + Math .floor ((idx1 + 1) / 2) * h

  ) % perimeter

  const idx2 = getIndex (w, h, r2)

  return {p1: randomPoint (es [idx1], rand), p2: randomPoint (es [idx2], rand)}

}


console .log (

  // Ten random pairs on rectangle with width 5 and height 2

  Array (10) .fill () .map (() => twoPoints (5, 2, rand))

)

唯一復雜的位是 的計算r2。我們通過將所有四個邊加在一起并減去當前邊的長度(width如果idx是偶數,height如果是奇數)來計算 0 和其余三個邊的總長度之間的隨機數。然后我們把它加到邊的總長度上,直到并包括索引(其中ceil和floor調用簡單地計算水平和垂直邊的數量,這些值分別乘以寬度和高度,并加在一起),最后取結果與周長的浮點模數。這與 jcalz 的答案中的技術相同,但通過處理邊長而不是簡單的計數而變得更加復雜。


我沒有創建rand任何類或接口的實例,實際上這里也沒有做任何 Typescript,但是你可以很容易地自己添加它。


查看完整回答
反對 回復 2021-08-26
?
小唯快跑啊

TA貢獻1863條經驗 獲得超2個贊

假設我們有以下接口和類型:


interface Rand {

  next(): number;

  between(x: number, y: number): number;

}

interface Point {

  x: number;

  y: number;

}

type PointPair = readonly [Point, Point];

并在評論中接受您的話,該程序是:首先隨機選擇兩個邊,然后在這些邊上隨機選擇點......首先讓我們看看隨機選擇兩個邊所涉及的內容:


  const s1 = Math.floor(rand.between(0, arr.length));

  const s2 = (Math.floor(rand.between(1, arr.length)) + s1) % arr.length; 

s1并s2代表arr我們正在選擇的索引。第一個選擇介于0和 小于數組長度之間的整數。我們通過0在數組的 和之間選擇一個實數(好吧,浮點數,無論如何),然后取該實數的下限來做到這一點。由于長度是4,我們正在做的是在0和之間均勻地選擇一個實數4。這些數字有四分之一之間0和1之間,另外四分之一1和2之間,一個季度2和3最后一個季度,并且之間3和4。這意味著你有 25% 的機會選擇每一個0,1,2和3。(選擇的機會4基本上為 0,或者如果rand以排除上限的正常方式實現,則可能恰好為 0 )。


因為s2我們現在1在數組的長度和之間均勻地選擇一個數字。在這種情況下,我們正在采摘1,2或3用33%的幾率各。我們將這個數字加到s1然后除以的余數4。想想我們正在做的事情是從第一邊開始s1,然后順時針移動 1、2 或 3 邊(比如)以選擇下邊。這完全消除了兩次選擇同一面的可能性。


現在讓我們看看在給定一個實例的情況下PointPair,在一條線段(可以定義為 a ,對應于線段的兩端p1和p2)上隨機選取一個點涉及什么Rand:


function randomPointOnSide([p1, p2]: PointPair, rand: Rand): Point {

  const frac = rand.next(); // between 0 and 1

  return { x: (p2.x - p1.x) * frac + p1.x, y: (p2.y - p1.y) * frac + p1.y };

}

在這里,我們做的就是選擇一個隨機數frac,沿途有多遠從代表p1到p2我們想去的地方。如果frac是0,我們選擇p1。如果frac是1,我們選擇p2。如果frac是0.5,我們選擇介于p1和之間的中間位置p2。造成這種情況的通式是之間的線性插值p1和p2給出frac。


希望在這兩者之間,您可以實現您正在尋找的算法。祝你好運!


查看完整回答
反對 回復 2021-08-26
  • 2 回答
  • 0 關注
  • 180 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號