Javascript 如何约束圆区域内的移动

Javascript 如何约束圆区域内的移动,javascript,geometry,Javascript,Geometry,这可能更像是一个与几何体相关的问题,但我试图将控制器约束在圆的某个区域内。我知道我必须接触Math.sin()和Math.cos()方法,但到目前为止我的尝试都没有结果 以下是JSFIDLE: 到目前为止,我已经能够将它约束到一个看不见的正方形上 var pointerell=document.getElementById(“指针”); var canvasEl=document.getElementById(“canvas”); 变量画布={ 宽度:canvasEl.offsetWidth,

这可能更像是一个与几何体相关的问题,但我试图将控制器约束在圆的某个区域内。我知道我必须接触Math.sin()和Math.cos()方法,但到目前为止我的尝试都没有结果

以下是JSFIDLE: 到目前为止,我已经能够将它约束到一个看不见的正方形上

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));
}