Как генерировать случайные непересекающиеся многоугольники без свободных пространств - PullRequest
2 голосов
/ 31 мая 2019

Мне нужно генерировать случайные непересекающиеся многоугольники без свободных пробелов (. Они могут иметь любую форму.

Единственное, что я нашел, это пример, который использует p5.js для создания только непересекающихся кругов,но свободные места есть.

Кто-нибудь знает, как это сделать?

// Uses P5.js for canvas creation and drawing
function setup() {
  var circles = [],
      circle = {},
      overlapping = false,
      NumCircles = 4000,
      protection = 1000,
      counter = 0,
      canvasWidth = window.innerWidth,
      canvasHeight = window.innerHeight;

  createCanvas(canvasWidth, canvasHeight);

  // populate circles array
  // brute force method continues until # of circles target is reached
  // or until the protection value is reached
  while (circles.length < NumCircles &&
         counter < protection) {
    circle = {
      x: random(width),
      y: random(height),
      r: random(3, 36)
    };
    overlapping = false;
    
    // check that it is not overlapping with any existing circle
    // another brute force approach
    for (var i = 0; i < circles.length; i++) {
      var existing = circles[i];
      var d = dist(circle.x, circle.y, existing.x, existing.y)
      if (d < circle.r + existing.r) {
        // They are overlapping
        overlapping = true;
        // do not add to array
        break;
      }
    }
    
    // add valid circles to array
    if (!overlapping) {
      circles.push(circle);      
    }
    
    counter++;
  }
  
  // circles array is complete
  // draw canvas once
  background("#233")
  fill("#2AC1A6");
  noStroke();
  for (var i = 0; i < circles.length; i++) {
    ellipse(circles[i].x, circles[i].y, 
            circles[i].r*2, circles[i].r*2);
  }
}
* {
  padding: 0;
  margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.4/p5.min.js"></script>

1 Ответ

1 голос
/ 31 мая 2019

Ваш вопрос не очень конкретен ...

случайные непересекающиеся многоугольники без свободных пространств

Прямоугольники - это многоугольники, давайте сделаем кучу из них со случайными размерами и цветами

Вот отправная точка:

canvas = document.getElementById('c');
ctx = canvas.getContext('2d');

var colors = ["red", "blue", "orange", "green", "yellow"]
h = Math.floor(canvas.height / Math.floor(Math.random() * 15 + 4))

for (y = 0; y < canvas.height; y += h) {
  w = Math.floor(canvas.width / Math.floor(Math.random() * 15 + 4))
  for (x = 0; x < canvas.width; x += w) {    
    c = colors[Math.floor(Math.random() * 10) % 5]
    draw(x, y, w, h, c)
  }
}

function draw(x, y, w, h, color) {
  ctx.beginPath();
  ctx.rect(x, y, w, h)
  ctx.stroke();
  ctx.fillStyle = color
  ctx.fill();
}
<canvas id="c"></canvas>

Вот функция, которая поможет вам нарисовать «случайные» полигоны:

var ctx = document.getElementById('c').getContext('2d');

function polygon(sides, size, Xcenter, Ycenter, offset) {
  ctx.beginPath();
  ctx.moveTo(Xcenter + size * Math.cos(offset), Ycenter + size * Math.sin(offset));
  for (var i = 1; i <= sides; i += 1) {
    x = Xcenter + size * Math.cos(i * 2 * Math.PI / sides +offset)
    y = Ycenter + size * Math.sin(i * 2 * Math.PI / sides +offset)
    ctx.lineTo(x, y);
  }
  ctx.stroke();
}

arr = [3, 4, 5, 6, 7];
arr.sort(() => Math.random() - 0.5);
for (var i = 1; i <= 5; i += 1) {
  offset = Math.random() * 5
  polygon(arr[i-1], 40, 85*i, 60, offset)
}
<canvas id="c" width=600></canvas>
...