html画布检查对象是不是成角度
Posted
技术标签:
【中文标题】html画布检查对象是不是成角度【英文标题】:html canvas check that object is in anglehtml画布检查对象是否成角度 【发布时间】:2018-06-21 05:59:15 【问题描述】:我有一个圆圈和一个对象。 我想画一个具有指定散布的圆段,然后检查对象是否处于定义的角度,如果是,角度颜色将为红色,否则为绿色。但是我的代码在某些情况下不起作用...
在这种情况下它可以工作:
这也是:
但这里不是:
我知道我的角度检测代码部分并不完美,但我不知道我能做什么。
这是我的代码:
html:
<html>
<head></head>
<body>
<canvas id="c" style="background-color: #DDD"></canvas>
<script src="script.js"></script>
</body>
</html>
js:
window.addEventListener('mousemove', updateMousePos, false);
var canvas = document.getElementById("c");
var context = canvas.getContext("2d");
//mouse coordinates
var mx = 0, my = 0;
draw();
function draw()
context.clearRect(0, 0, canvas.width, canvas.height);
//object coordinates
var ox = 350, oy = 260;
context.beginPath();
context.arc(ox,oy,5,0,2*Math.PI);
context.fill();
//circle
var cx = 400, cy = 280;
var r = 100;
var segmentPoints = 20;
var circlePoints = 40;
var spread = Math.PI / 2;
var mouseAngle = Math.atan2(my - cy, mx - cx); //get angle between circle center and mouse position
context.beginPath();
context.strokeStyle = "blue";
context.moveTo(cx + r, cy);
for(var i=0; i<circlePoints; i++)
var a = 2 * Math.PI / (circlePoints - 1) * i;
var x = cx + Math.cos(a) * r;
var y = cy + Math.sin(a) * r;
context.lineTo(x, y);
context.lineTo(cx + r, cy);
context.stroke();
var objAngle = Math.atan2(oy - cy, ox - cx);
var lowerBorder = mouseAngle - spread / 2;
var biggerBorder = mouseAngle + spread / 2;
/////////////////////////////////////////////ANGLES DETECTION PART
if(objAngle >= lowerBorder && objAngle <= biggerBorder ||
objAngle <= biggerBorder && objAngle >= lowerBorder)
context.strokeStyle = "red";
else
context.strokeStyle = "green";
context.lineWidth = 3;
//angle center line
context.beginPath();
context.moveTo(cx, cy);
context.lineTo(cx + Math.cos(mouseAngle) * r * 2, cy + Math.sin(mouseAngle) * r * 2);
context.stroke();
//draw spread arc
context.beginPath();
context.moveTo(cx, cy);
for(var i=0; i<segmentPoints; i++)
var a = mouseAngle - spread / 2 + spread / (segmentPoints - 1) * i;
var x = cx + Math.cos(a) * r;
var y = cy + Math.sin(a) * r;
context.lineTo(x, y);
context.lineTo(cx, cy);
context.stroke();
//show degrees
context.font = "20px Arial";
context.fillText((lowerBorder * 180 / Math.PI).toFixed(2), Math.cos(lowerBorder) * r + cx, Math.sin(lowerBorder) * r + cy);
context.fillText((biggerBorder * 180 / Math.PI).toFixed(2), Math.cos(biggerBorder) * r + cx, Math.sin(biggerBorder) * r + cy);
context.fillText((mouseAngle * 180 / Math.PI).toFixed(2), Math.cos(mouseAngle) * r + cx, Math.sin(mouseAngle) * r + cy);
//update
setTimeout(function() draw(); , 10);
//getting mouse coordinates
function updateMousePos(evt)
var rect = document.getElementById("c").getBoundingClientRect();
mx = evt.clientX - rect.left;
my = evt.clientY - rect.top;
【问题讨论】:
你在 strokeStype = "green"; 之后少了一个 ; 对于它的价值,对应于角度的数字似乎很奇怪。传统上,3 点钟是零度,随着角度的增加,您逆时针扫过。因此,前 2 个图表看起来没问题,尽管在每个图表之前都有一个错误的-
。
【参考方案1】:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
body
background-color: black;
canvas
position: absolute;
margin: auto;
left: 0;
right: 0;
border: solid 1px white;
border-radius: 10px;
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="application/javascript">
// Rotation here is being measured in Radians
// Given two 2D vectors A & B, the angle between them can be drawn from this formula
// A dot B = length(a) * length(b) * cos(angle)
// if the vectors are normalized (the length is 1) the formula becomes
// A dot B = cos(angle)
// angle = acos(a.x * b.x + a.y * b.y)
// So here you are concerned with the direction of the two vectors
// One will be the vector facing outward from the middle of your arc segment
// The other will be a directional vector from the point you want to do collision with to the center
// of the circle
var canvasWidth = 180;
var canvasHeight = 160;
var canvas = null;
var ctx = null;
var bounds = top: 0.0, left: 0.0;
var circle =
x: (canvasWidth * 0.5)|0,
y: (canvasHeight * 0.5)|0,
radius: 50.0,
rotation: 0.0, // In Radians
arcSize: 1.0
;
var point =
x: 0.0,
y: 0.0
;
window.onmousemove = function(e)
point.x = e.clientX - bounds.left;
point.y = e.clientY - bounds.top;
// runs after the page has loaded
window.onload = function()
canvas = document.getElementById("canvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
bounds = canvas.getBoundingClientRect();
ctx = canvas.getContext("2d");
loop();
function loop()
// Update Circle Rotation
circle.rotation = circle.rotation + 0.025;
if (circle.rotation > 2*Math.PI)
circle.rotation = 0.0;
// Vector A (Point Pos -> Circle Pos)
var aX = circle.x - point.x;
var aY = circle.y - point.y;
var aLength = Math.sqrt(aX * aX + aY * aY);
// Vector B (The direction the middle of the arc is facing away from the circle)
var bX = Math.sin(circle.rotation);
var bY =-Math.cos(circle.rotation); // -1 is facing upward, not +1
var bLength = 1.0;
// Normalize vector A
aX = aX / aLength;
aY = aY / aLength;
// Are we inside the arc segment?
var isInsideRadius = aLength < circle.radius;
var isInsideAngle = Math.abs(Math.acos(aX * bX + aY * bY)) < circle.arcSize * 0.5;
var isInsideArc = isInsideRadius && isInsideAngle;
// Clear the screen
ctx.fillStyle = "gray";
ctx.fillRect(0,0,canvasWidth,canvasHeight);
// Draw the arc
ctx.strokeStyle = isInsideArc ? "green" : "black";
ctx.beginPath();
ctx.moveTo(circle.x,circle.y);
ctx.arc(
circle.x,
circle.y,
circle.radius,
circle.rotation - circle.arcSize * 0.5 + Math.PI * 0.5,
circle.rotation + circle.arcSize * 0.5 + Math.PI * 0.5,
false
);
ctx.lineTo(circle.x,circle.y);
ctx.stroke();
// Draw the point
ctx.strokeStyle = "black";
ctx.fillStyle = "darkred";
ctx.beginPath();
ctx.arc(
point.x,
point.y,
5.0,
0.0,
2*Math.PI,
false
);
ctx.fill();
ctx.stroke();
// This is better to use then setTimeout()
// It automatically syncs the loop to 60 fps for you
requestAnimationFrame(loop);
</script>
</body>
</html>
【讨论】:
以上是关于html画布检查对象是不是成角度的主要内容,如果未能解决你的问题,请参考以下文章