gpt4 book ai didi

javascript - 如何画一个n边任意的不规则多边形?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:37:28 25 4
gpt4 key购买 nike

我正在尝试找到一种算法来绘制一个简单的(不允许直线相交)的不规则多边形。

边数由用户定义,n>3

这是一个只绘制复杂多边形(线相交)的初始代码:

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

var sides = 10;

ctx.fillStyle = '#f00';
ctx.beginPath();
ctx.moveTo(0, 0);

for(var i=0;i<sides;i++)
{
var x = getRandomInt(0, 100);
var y = getRandomInt(0, 100);
ctx.lineTo(x, y);
}
ctx.closePath();
ctx.fill();

// https://stackoverflow.com/a/1527820/1066234
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}

JSFiddle:https://jsfiddle.net/kai_noack/op2La1jy/6/

我不知道如何确定连接线的下一个点,这样它就不会切断任何其他线。

此外,最后一个点必须闭合多边形。

这是生成的多边形之一的示例:

simple irregular polygon example

编辑:我今天认为一种可能的算法是规则地排列多边形点(例如作为矩形),然后将它们在 x-y 方向上重新定位到随机数量,同时检查生成的线是否被切割。

最佳答案

我移植了这个solution到 Javascript 1 到 1。代码看起来不是最优的,但会产生随机凸(但仍然不规则)多边形。

//shuffle array in place
function shuffle(arr) {
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr;
}

/** Based on Sander Verdonschot java implementation **/

class Point {
constructor(x, y) {
this.x = x;
this.y = y
}
}

function generateRandomNumbersArray(len) {
const result = new Array(len);
for (let i = 0; i < len; ++i) {
result[i] = Math.random();
}
return result;
}

function generateRandomConvexPolygon(vertexNumber) {
const xPool = generateRandomNumbersArray(vertexNumber);
const yPool = generateRandomNumbersArray(vertexNumber);

// debugger;
xPool.sort();
yPool.sort();

const minX = xPool[0];
const maxX = xPool[xPool.length - 1];
const minY = yPool[0];
const maxY = yPool[yPool.length - 1];

const xVec = []
const yVec = [];

let lastTop = minX;
let lastBot = minX;

xPool.forEach(x => {
if (Math.random() >= 0.5) {
xVec.push(x - lastTop);
lastTop = x;
} else {
xVec.push(lastBot - x);
lastBot = x;
}
});

xVec.push(maxX - lastTop);
xVec.push(lastBot - maxX);

let lastLeft = minY;
let lastRight = minY;

yPool.forEach(y => {
if (Math.random() >= 0.5) {
yVec.push(y - lastLeft);
lastLeft = y;
} else {
yVec.push(lastRight - y);
lastRight = y;
}
});

yVec.push(maxY - lastLeft);
yVec.push(lastRight - maxY);

shuffle(yVec);

vectors = [];
for (let i = 0; i < vertexNumber; ++i) {
vectors.push(new Point(xVec[i], yVec[i]));
}

vectors.sort((v1, v2) => {
if (Math.atan2(v1.y, v1.x) > Math.atan2(v2.y, v2.x)) {
return 1;
} else {
return -1;
}
});

let x = 0, y = 0;
let minPolygonX = 0;
let minPolygonY = 0;
let points = [];

for (let i = 0; i < vertexNumber; ++i) {
points.push(new Point(x, y));
x += vectors[i].x;
y += vectors[i].y;

minPolygonX = Math.min(minPolygonX, x);
minPolygonY = Math.min(minPolygonY, y);
}

// Move the polygon to the original min and max coordinates
let xShift = minX - minPolygonX;
let yShift = minY - minPolygonY;

for (let i = 0; i < vertexNumber; i++) {
const p = points[i];
points[i] = new Point(p.x + xShift, p.y + yShift);
}

return points;
}


function draw() {
const vertices = 10;
const _points = generateRandomConvexPolygon(vertices);

//apply scale
const points = _points.map(p => new Point(p.x * 300, p.y * 300));

const ctx = document.getElementById('drawpolygon').getContext('2d');


ctx.fillStyle = '#f00';
ctx.beginPath();
ctx.moveTo(points[0].x, points[0].y);

for(let i = 1; i < vertices ; ++i)
{
let x = points[i].x;
let y = points[i].y;
ctx.lineTo(x, y);
}
ctx.closePath();
ctx.fill();
}

draw();
<canvas id="drawpolygon"></canvas>

关于javascript - 如何画一个n边任意的不规则多边形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55360763/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com