How to constrain movement within the area of a circle

前端 未结 4 1752
星月不相逢
星月不相逢 2020-12-03 19:27

This might be more a geometry related question, but I\'m trying to constrain a controller within an area of a circle. I know I have to touch the Math.sin() and Math.cos() me

4条回答
  •  [愿得一人]
    2020-12-03 19:56

    Hi and thanks for sharing your solution.

    Your jsfiddle helps me a lot to constraint the movement of a rotation handle.

    Here's my solution using jQuery :

    function getBall(xVal, yVal, dxVal, dyVal, rVal, colorVal) {
      var ball = {
        x: xVal,
        lastX: xVal,
        y: yVal,
        lastY: yVal,
        dx: dxVal,
        dy: dyVal,
        r: rVal,
        color: colorVal,
        normX: 0,
        normY: 0
      };
    
      return ball;
    }
    
    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";
    
    var balls = [
      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")
    ];
    
    function draw() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
    
      for (var i = 0; i < balls.length; i++) {
        var curBall = balls[i];
        ctx.beginPath();
        ctx.arc(curBall.x, curBall.y, curBall.r, 0, Math.PI * 2);
        ctx.fillStyle = curBall.color;
        ctx.fill();
        ctx.closePath();
        curBall.lastX = curBall.x;
        curBall.lastY = curBall.y;
        curBall.x += curBall.dx;
        curBall.y += curBall.dy;
        var dx = curBall.x - containerR;
        var dy = curBall.y - containerR;
        var distanceFromCenter = Math.sqrt(dx * dx + dy * dy);
    
        if (distanceFromCenter >= containerR - curBall.r) {
          var normalMagnitude = distanceFromCenter;
          var normalX = dx / normalMagnitude;
          var normalY = dy / normalMagnitude;
          var tangentX = -normalY;
          var tangentY = normalX;
          var normalSpeed = -(normalX * curBall.dx + normalY * curBall.dy);
          var tangentSpeed = tangentX * curBall.dx + tangentY * curBall.dy;
          curBall.dx = normalSpeed * normalX + tangentSpeed * tangentX;
          curBall.dy = normalSpeed * normalY + tangentSpeed * tangentY;
        }
    
        xLabel.innerText = "x: " + curBall.x;
        yLabel.innerText = "y: " + curBall.y;
        dxLabel.innerText = "dx: " + curBall.dx;
        dyLabel.innerText = "dy: " + curBall.dy;
      }
      requestAnimationFrame(draw);
    }
    
    draw();
    canvas { background: #eee; }

    Hope this help someone.

提交回复
热议问题