簡體   English   中英

我該如何制作正方形?

[英]How can I make squares?

我試圖生成隨機,凸,非自相交的多邊形 - 特別是四邊形。

我已經達到了:

function randquad(){

          var bodyDef = new b2BodyDef,
              fixDef = new b2FixtureDef,
              x=0, y=0;

          fixDef.density = Math.random();
          fixDef.friction = Math.random();
          fixDef.restitution = Math.random()*0.3;

          bodyDef.type = b2Body.b2_dynamicBody;
          fixDef.shape = new b2PolygonShape;
          fixDef.shape.SetAsArray([
            new b2Vec2(x, y),
            new b2Vec2(x+=Math.random()*2, y+=Math.random()*2*(Math.random()<0.5?1:-1)),
            new b2Vec2(x+=Math.random()*2*(Math.random()<0.5?1:-1), y+=Math.random()*2),
            new b2Vec2(x-=Math.random()*2, y+=Math.random()*2*(Math.random()<0.5?1:-1))
          ]);
          bodyDef.position.x = Math.random() * 10;
          bodyDef.position.y = 0;
          world.CreateBody(bodyDef).CreateFixture(fixDef);
        }

我正在使用Box2D網絡; 然而,這個問題並不局限於它,或者javascript - 它是一個更廣泛的數學問題。

我希望得到4分,按順序,形成我正在尋找的形狀。

根據我寫的代碼,我經常得到理想的形狀; 但是,我仍然會得到自相交的形狀。 目前我對凸起的形狀並不太感興趣。

我需要這樣的形狀的原因是因為它似乎是box2d web喜歡的唯一。

任何4點可以使非自相交的四邊形對嗎? 我應該最初生成4,並將它們分類成一個有效的序列嗎? 什么是最好/最有效的方式來接近這個?

- 原始題目:隨機四邊形生成

你可以從這樣一個事實開始:如果你取3個隨機點,它們將總是形成一個凸的,不相交的三角形(假設這些點都是不同的)。 然后你可以通過沿着最后一個邊緣添加一個隨機距離的第四個點,然后將它從三角形的中心推出一個隨機量來彈出其中一個邊緣。

  • 首先通過生成3個隨機點生成隨機三角形:A,B,C
  • 選擇介於0和1之間的隨機數,並使用它來計算沿C和A之間的某個點的某個點的D點
  • 通過平均A,B,C計算三角形的質心
  • 計算1到n之間的另一個隨機數(比如2)
  • 計算從質心到D的向量(從D中減去質心),然后將它乘以第二個隨機數,然后加回到質心。 這將產生你的第四點。

我不確定你是否有任何美學要求(例如沒有過分尖銳的形狀)但你可以隨意使用隨機數生成一點來獲得你喜歡的結果。 例如,在第二步中,您可以選擇介於0.2和0.8之間的隨機數,因此這些點不會太靠近。 您還可以在第四步中更改n的值。

另一個問題是纏繞。 使用這種方法,一半四邊形將具有順時針繞組並且將是逆時針方向。 如果你需要一個特定的繞組,你可以做一個繞組測試(BC的點積與AB的法線的符號),如果它不是你想要的那樣,那么只需要反映一個軸上的所有點。

如果從圓周邊取出點,則所有頂點都將凸出。

知道了這一點,我們可以編程一個循環來分支到一個不存在的圓並產生總是會產生凸形的角。

angles=[];
for (var i = 4; i--;) angles.push(Math.random()*2*Math.PI);

現在需要對角度進行排序,因此在創建形狀時,順時針方向,它們按角度大小的順序選擇。 這將阻止形狀的點交叉/自交。

angles.sort()

現在您可以使用三角函數cossin創建形狀,這些將角度轉換為實際坐標。

polygon([
    vector(Math.cos(angles[0]), Math.sin(angles[0])),
    vector(Math.cos(angles[1]), Math.sin(angles[1])),
    vector(Math.cos(angles[2]), Math.sin(angles[2])),
    vector(Math.cos(angles[3]), Math.sin(angles[3]))
]);`

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM