2016-09-28 4 views
1

Я пытаюсь создать случайные, выпуклые, несамопересекающиеся многоугольники - quadrilaterals.Как я могу сделать квадраты?

я получил, насколько:

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.

Любые 4 очка могут сделать несамопересекающиеся четырехугольники вправо? Должен ли я генерировать 4 изначально и сортировать их в последовательности, которая работает? Какой лучший/самый эффективный способ для этого?

- Оригинальный Вопрос Название: Случайные Четырехугольник поколение

ответ

0

Вы могли бы исходить из того, что если взять 3 случайных точек, они всегда образуют выпуклые, не пересекающихся треугольника (при условии, что точки все разные) , Затем вы можете просто вытащить один из краев, добавив четвертую точку на случайное расстояние вдоль последнего края и отталкивая ее от центра треугольника случайным количеством.

  • Начнитесь генерации случайного треугольник путем генерирования 3 случайных точек: A, B, C
  • Выберите случайное число между 0 и 1, и использовать его, чтобы вычислить точку D где-то вдоль линии между C и а
  • Вычислить центроид треугольника путем усреднения A, B, C
  • Вычислить другое случайное число в диапазоне от 1 до п (скажем 2)
  • Вычислить вектор из центроида в D (вычесть центроид из D), и умножьте его на это второе случайное число, затем добавьте обратно в центр тяжести. Это даст вам четвертый пункт.

Я не уверен, что у вас есть какие-либо эстетические требования (например, без чрезмерно точечных форм), но вы можете немного поиграть с генерацией случайных чисел, чтобы получить нужные вам результаты. Например, на втором этапе вы можете выбрать случайное число между 0,2 и 0,8, например, так что точки не слишком близко друг к другу. Вы также можете изменить значение n на четвертом шаге.

Другая проблема - обмотка. С помощью этого метода половина квадов будет иметь по часовой стрелке обмотку и будет вращаться против часовой стрелки. Если вам нужна конкретная обмотка, вы можете выполнить проверку намотки (знак точечного продукта BC с нормальным значением AB), и если это не так, как вы хотите, просто отразите все точки на одной оси.

0

Если вы берете свои точки по периметру круга, все вершины будут выпуклыми.

Зная это, мы можем запрограммировать цикл, чтобы разветвиться на несуществующий круг и создать углы, которые всегда будут иметь выпуклую форму.

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

Теперь углы должны быть отсортированы так, когда создается форма, по часовой стрелке, они выбираются в порядке размера угла. Это остановит точки пересечения/самопересечения формы.

angles.sort() 

Теперь вы можете создать форму с помощью функции triganometric cos и sin, это будет преобразовывать угол к реальным координатам.

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])) 
]);`