Javascript 如何约束圆区域内的移动
这可能更像是一个与几何体相关的问题,但我试图将控制器约束在圆的某个区域内。我知道我必须接触Math.sin()和Math.cos()方法,但到目前为止我的尝试都没有结果 以下是JSFIDLE: 到目前为止,我已经能够将它约束到一个看不见的正方形上Javascript 如何约束圆区域内的移动,javascript,geometry,Javascript,Geometry,这可能更像是一个与几何体相关的问题,但我试图将控制器约束在圆的某个区域内。我知道我必须接触Math.sin()和Math.cos()方法,但到目前为止我的尝试都没有结果 以下是JSFIDLE: 到目前为止,我已经能够将它约束到一个看不见的正方形上 var pointerell=document.getElementById(“指针”); var canvasEl=document.getElementById(“canvas”); 变量画布={ 宽度:canvasEl.offsetWidth,
var pointerell=document.getElementById(“指针”);
var canvasEl=document.getElementById(“canvas”);
变量画布={
宽度:canvasEl.offsetWidth,
高度:canvasEl.offsetHeight,
顶部:canvasEl.offsetTop,
左:canvasEl.offsetLeft
};
canvas.center=[canvas.left+canvas.width/2,canvas.top+canvas.height/2];
canvas.radius=canvas.width/2;
window.onmousemove=函数(e){
var结果=极限(e.x,e.y);
如果(!result.limit){
pointer.style.left=result.x+“px”;
pointer.style.top=result.y+“px”;
}
}
功能极限(x,y){
var dist=距离([x,y],画布中心);
if(dist只要对每个数据点(预期位置)进行规范化,这个算法就很简单,我已经在下面的函数中尝试过这样做:
function locatePoint(canvas_size, next_position) {
// canvas_size & next_position are both 2-element arrays
// (w, h) & (x, y)
dist = function(x, y) {
return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
};
x = next_position[0];
y = next_position[1];
rescaledX = x/(canvas_size[0]/2);
rescaledY = y/(canvas_size[1]/2);
if (distance(x, y) <= 1) {
// the base case; position is w/in the circle
}
else {
// position is outside the circle, so perhaps
// do something like random select a new position, then
// call this function again (recursively) passing in
// that new position
}
}
功能定位点(画布大小、下一个位置){
//画布大小和下一个位置都是2元素数组
//(w,h)和(x,y)
距离=函数(x,y){
返回Math.sqrt(Math.pow(x,2)+Math.pow(y,2));
};
x=下一个位置[0];
y=下一个位置[1];
重新缩放x=x/(画布大小[0]/2);
重新缩放=y/(画布大小[1]/2);
如果(距离(x,y),那么在大家的帮助下,我终于能够完成这项工作
var pointerEl = document.getElementById("pointer");
var canvasEl = document.getElementById("canvas");
var canvas = {
width: canvasEl.offsetWidth,
height: canvasEl.offsetHeight,
top: canvasEl.offsetTop,
left: canvasEl.offsetLeft
};
canvas.center = [canvas.left + canvas.width / 2, canvas.top + canvas.height / 2];
canvas.radius = canvas.width / 2;
window.onmousemove = function(e) {
var result = limit(e.x, e.y);
pointer.style.left = result.x + "px";
pointer.style.top = result.y + "px";
}
function limit(x, y) {
var dist = distance([x, y], canvas.center);
if (dist <= canvas.radius) {
return {x: x, y: y};
}
else {
x = x - canvas.center[0];
y = y - canvas.center[1];
var radians = Math.atan2(y, x)
return {
x: Math.cos(radians) * canvas.radius + canvas.center[0],
y: Math.sin(radians) * canvas.radius + canvas.center[1]
}
}
}
function distance(dot1, dot2) {
var x1 = dot1[0],
y1 = dot1[1],
x2 = dot2[0],
y2 = dot2[1];
return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
}
var pointerell=document.getElementById(“指针”);
var canvasEl=document.getElementById(“canvas”);
变量画布={
宽度:canvasEl.offsetWidth,
高度:canvasEl.offsetHeight,
顶部:canvasEl.offsetTop,
左:canvasEl.offsetLeft
};
canvas.center=[canvas.left+canvas.width/2,canvas.top+canvas.height/2];
canvas.radius=canvas.width/2;
window.onmousemove=函数(e){
var结果=极限(e.x,e.y);
pointer.style.left=result.x+“px”;
pointer.style.top=result.y+“px”;
}
功能极限(x,y){
var dist=距离([x,y],画布中心);
if(dist您好,感谢您分享您的解决方案
您的JSFIDLE在约束旋转手柄的移动方面帮了我很大的忙
下面是我使用jQuery的解决方案:
函数getBall(xVal、yVal、dxVal、dyVal、rVal、colorVal){
变量球={
x:xVal,
lastX:xVal,
y:伊瓦尔,
拉蒂:伊瓦尔,
dx:dxVal,
迪瓦:迪瓦,
r:rVal,
颜色:colorVal,
normX:0,
正常值:0
};
回球;
}
var canvas=document.getElementById(“myCanvas”);
var xLabel=document.getElementById(“x”);
var yLabel=document.getElementById(“y”);
var dxLabel=document.getElementById(“dx”);
var dyLabel=document.getElementById(“dy”);
var ctx=canvas.getContext(“2d”);
var-containerR=200;
canvas.width=containerR*2;
canvas.height=containerR*2;
canvas.style[“border radius”]=containerR+“px”;
变量球=[
getBall(containerR,containerR*2-30,2-2,20,“#0095DD”),
getBall(containerR,containerR*2-50,3-3,30,“#DD9500”),
getBall(containerR,containerR*2-60,-3,4,10,“#00DD95”),
getBall(containerR,containerR*2/5,-1.5,3,40,“#DD0095”)
];
函数绘图(){
clearRect(0,0,canvas.width,canvas.height);
对于(变量i=0;i=containerR-curBall.r){
var normalMagnitude=距中心的距离;
var normalX=dx/法线幅值;
var normalY=dy/normalmagnity;
var切线X=-法线;
var切线=法线x;
var normalSpeed=-(normalX*corball.dx+normalY*corball.dy);
var切向速度=切向x*corball.dx+切向*corball.dy;
curBall.dx=正常速度*normalX+切向速度*切线x;
curBall.dy=正常速度*正常+切向速度*切向;
}
xLabel.innerText=“x:+curBall.x;
yLabel.innerText=“y:+curBall.y;
dxlab.innerText=“dx:+curBall.dx;
dyLabel.innerText=“dy:”+curBall.dy;
}
请求动画帧(绘制);
}
draw();
canvas{background:#eee;}
您需要确保x^2+y^2我已将您的小提琴更新为:-我不是数学天才,所以我尝试了一种蛮力方法来寻找有效的x/y组合。它还没有完成,但我已经没有时间了。我希望您可以用它作为一个跳转点来找到您的解决方案-目标是摆脱循环中的安全网(break子句)-快乐编码;)非常感谢!我确实需要点“跟随”光标,即使它不在圆上,我也会尝试阅读一些几何图形。非常感谢您的解释。在else
语句中(光标在圆外),找到光标和圆心之间的角度,并将圆点沿圆周放置在相应的角度,这是一个好策略吗?我想你可以,但它更容易,例如,将坐标对乘以某个折扣因子(小于1)然后用距离函数计算这对新的坐标。我假设你不在乎光标在圆内的什么位置,只是它在圆内的某个地方。我需要它位于圆的边缘,就像它在跟随光标一样。因此,沿单位圆边缘的坐标对由x=cos(θ)给出y=sin(θ);θ是
var pointerEl = document.getElementById("pointer");
var canvasEl = document.getElementById("canvas");
var canvas = {
width: canvasEl.offsetWidth,
height: canvasEl.offsetHeight,
top: canvasEl.offsetTop,
left: canvasEl.offsetLeft
};
canvas.center = [canvas.left + canvas.width / 2, canvas.top + canvas.height / 2];
canvas.radius = canvas.width / 2;
window.onmousemove = function(e) {
var result = limit(e.x, e.y);
pointer.style.left = result.x + "px";
pointer.style.top = result.y + "px";
}
function limit(x, y) {
var dist = distance([x, y], canvas.center);
if (dist <= canvas.radius) {
return {x: x, y: y};
}
else {
x = x - canvas.center[0];
y = y - canvas.center[1];
var radians = Math.atan2(y, x)
return {
x: Math.cos(radians) * canvas.radius + canvas.center[0],
y: Math.sin(radians) * canvas.radius + canvas.center[1]
}
}
}
function distance(dot1, dot2) {
var x1 = dot1[0],
y1 = dot1[1],
x2 = dot2[0],
y2 = dot2[1];
return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
}