캔버스로 볼록포 그리기
볼록포란, 위키 에도 있지만 간단하게 말하면 고무를 걸은 것 같은 상태.
할 일
점을 뿌리다
우선은 랜덤으로 100개의 좌표를 만들고 좌표의 위치에 점을 그립니다.
좌표를 만들어 그리기
// canvasを取得
var canvas = document.getElementById('canvas');
// canvasを画面サイズにする
canvas.width = document.documentElement.clientWidth;
canvas.height = document.documentElement.clientHeight;
// contextを取得
var context = canvas.getContext('2d');
// 点を入れる配列
var points = [];
// あまり端に行き過ぎないように乱数を作成
var margin = 100;
for (var i = 0; i < 100; i++) {
points.push({
x: (Math.random() * (canvas.width - margin * 2) + margin) | 0,
y: (Math.random() * (canvas.height - margin * 2) + margin) | 0
});
}
// 点を描画
context.fillStyle = '#00f';
points.forEach(function (point) {
context.beginPath();
context.arc(point.x, point.y, 1, 0, Math.PI*2);
context.fill();
});
이런 느낌.
최소 볼록 세트를 찾는다.
이 부분의 처리는 여러가지 방법이 있을 것 같지만, 이번은 다음과 같이 하여 볼록 집합을 요구했다.
theta를 계산하는 함수는 이런 느낌.
getTheta
// 座標同士の角度を計算
var getTheta = function (point1, point2) {
var width = point2.x - point1.x,
height = point2.y - point1.y,
radian = Math.atan(height / width),
theta = radian * (180 / Math.PI);
// arctanの返り値は -90 <= 角度 <= 90 なので、
// 座標の象限によって値の調整を行う
if (width >= 0 && height >= 0) {
theta += 0;
} else if ((width < 0 && height >= 0) || (width < 0 && height < 0)) {
theta += 180;
} else {
theta += 360;
}
return theta;
};
100개의 좌표로부터 볼록 집합을 구하는 함수는 이런 느낌.
getConvexPoints
var getConvexPoints = function (points) {
var convexPoints = [];
// 一番小さいYを取得
var minY = points.reduce(function (min, point) {
return Math.min(min, point.y);
}, Infinity);
// 一番小さいYを持つ中で、一番小さいXを持つ点を取得
var C1 = points.filter(function (point) {
return point.y === minY;
}).sort(function (a, b) {
return a.x - b.x;
})[0];
convexPoints.push(C1);
var Cn = C1;
// 起点から時計回りに次の点を起点を走査していく
while (1) {
var minTheta = Infinity,
cLength = convexPoints.length,
borderTheta = cLength === 1 ? 0 : (function () {
var current = convexPoints[cLength-1],
prev = convexPoints[cLength-2];
return getTheta(prev, current)
})(),
index = -1;
points.forEach(function (point, i) {
if (point === Cn || point == null) { return; }
var theta = getTheta(Cn, point);
if (minTheta >= theta && theta >= borderTheta) {
minTheta = theta;
index = i;
}
});
Cn = points[index];
if (Cn === C1) { break; }
convexPoints.push(Cn);
};
return convexPoints;
};
선을 그리다
마지막으로, 구한 볼록 세트의 좌표를 따라 선을 그립니다.
선을 그리다
var convexPoints = getConvexPoints(points);
context.strokeStyle = '#000';
context.beginPath();
convexPoints.forEach(function (point) {
context.lineTo(point.x, point.y);
});
context.closePath();
context.stroke();
이런 느낌.
하지만
Reference
이 문제에 관하여(캔버스로 볼록포 그리기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/keiskimu/items/dfd734eceb4236b66f7e텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)