有简单形状(红色三角形)和复杂形状(黑色“U 形”)。 我用鼠标绘制蓝色形状并愿意找到:被绘图覆盖的图形的百分比(蓝色)。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Canvas</title>
<style>
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="canvas" width="800" height="600"></canvas>
<script>
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const radius = 15;
const random_shape = [
{ x: 20, y: 20, width: 20, height: 100 },
{ x: 60, y: 20, width: 20, height: 100 },
{ x: 20, y: 120, width: 60, height: 20 },
];
const triangle = [
{ x: 200, y: 400 },
{ x: 400, y: 200 },
{ x: 600, y: 400 },
];
let isDrawing = false;
let lastX = 0;
let lastY = 0;
let pixelsInsideFigure = 0;
function draw_random_shape() {
for (let i = 0; i < random_shape.length; i++) {
ctx.fillStyle = "black";
ctx.fillRect(
random_shape[i].x,
random_shape[i].y,
random_shape[i].width,
random_shape[i].height
);
}
}
function draw_triangle() {
ctx.beginPath();
ctx.moveTo(triangle[0].x, triangle[0].y);
for (let i = 1; i < triangle.length; i++) {
ctx.lineTo(triangle[i].x, triangle[i].y);
}
ctx.closePath();
ctx.fillStyle = "red";
ctx.fill();
}
function handleMouseDown(e) {
isDrawing = true;
[lastX, lastY] = [e.offsetX, e.offsetY];
if (pointInShape({ x: lastX, y: lastY }, random_shape)) {
pixelsInsideFigure++;
}
}
function handleMouseMove(e) {
if (!isDrawing) return;
ctx.strokeStyle = "blue";
ctx.lineJoin = "round";
ctx.lineCap = "round";
ctx.lineWidth = radius;
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
[lastX, lastY] = [e.offsetX, e.offsetY];
if (pointInShape({ x: lastX, y: lastY }, random_shape)) {
pixelsInsideFigure++;
}
}
function handleMouseUp() {
isDrawing = false;
calculatePercentage();
pixelsInsideFigure = 0;
}
function clearUserInput() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
draw_triangle();
draw_random_shape();
}
function calculatePercentage() {
const coveredArea = calculateCoveredArea(
{ x: lastX, y: lastY },
radius
);
const totalArea = Math.PI * Math.pow(radius, 2);
const coveragePercentage = (coveredArea / totalArea) * 100;
alert(`Area Coverage Percentage: ${coveragePercentage.toFixed(2)}%`);
clearUserInput();
}
function pointInShape(point, vertices) {
let inside = false;
const x = point.x;
const y = point.y;
for (let i = 0, j = vertices.length - 1; i < vertices.length; j = i++) {
const xi = vertices[i].x;
const yi = vertices[i].y;
const xj = vertices[j].x;
const yj = vertices[j].y;
const intersect =
yi > y != yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;
if (intersect) inside = !inside;
}
return inside;
}
function calculateCoveredArea(point, radius) {
let coveredArea = 0;
const centerX = point.x;
const centerY = point.y;
for (let x = centerX - radius; x <= centerX + radius; x++) {
for (let y = centerY - radius; y <= centerY + radius; y++) {
const distance = Math.sqrt(
Math.pow(x - centerX, 2) + Math.pow(y - centerY, 2)
);
if (distance <= radius) {
if (pointInShape({ x: x, y: y }, random_shape)) {
console.log("INSIDE RANDOM SHAPE");
coveredArea++;
}
if (pointInShape({ x: x, y: y }, triangle)) {
console.log("INSIDE Triangle");
coveredArea++;
}
}
}
}
return coveredArea;
}
function calculateArea(vertices) {
let area = 0;
for (let i = 0, j = vertices.length - 1; i < vertices.length; j = i++) {
area +=
(vertices[j].x + vertices[i].x) * (vertices[j].y - vertices[i].y);
}
return Math.abs(area / 2);
}
function init() {
draw_triangle();
draw_random_shape();
canvas.addEventListener("mousedown", handleMouseDown);
canvas.addEventListener("mousemove", handleMouseMove);
canvas.addEventListener("mouseup", handleMouseUp);
}
init();
</script>
</body>
</html>
附注作为《哈利·波特 1》中的参考,我必须引导一根魔杖来适应形状。要通过技能,您必须正确覆盖该区域。
在提供的情况下,我预计能达到 60-70% 左右(左上角)。
在互联网上搜索,询问“机器人”,进行数学调整 - 没有帮助。 期望:计算和查找面积百分比的正确方法。
我首先想到的是,您可以计算用户绘制后显示的总像素,然后您可以与目标形状像素数进行比较。只是一个想法