javascript - 获取 Canvas 绘制的上下文线的边界(位置)

标签 javascript html canvas

我正在做一些物理测试。我使用 Canvas 和上下文绘制了一个带有线条的圆圈:

function drawAngles () {
    var d = 50; //start line at (10, 20), move 50px away at angle of 30 degrees
    var angle = 80 * Math.PI/180;
    ctx.beginPath();
    ctx.moveTo(300,0);
    ctx.lineTo(300,600); //x, y
    ctx.moveTo(0,300);
    ctx.lineTo(600,300);
    ctx.arc(300,300,300,0,2*Math.PI);
    ctx.stroke();
}

我想以某种方式获得圆的弯曲边界,这样我就可以判断球元素是否发生了碰撞。

如果我在典型的 div 上测试边界,我可以这样做:

var divCoords= $(".boundingBoxDiv").position();
var top = divCoords.top;
etc...

如何使用上下文行执行此操作?

这是一张图片...球应该从圆圈中弹起。

enter image description here

最佳答案

<强> Live Demo

这很容易实现,在基于半径的碰撞中,您只需检查距离是否比物体碰撞的半径更近。在这种情况下,我们需要做相反的事情,如果物体距离大于边界半径,我们需要改变 Angular 以保持物体在其中。

所以首先我们需要确定边界中心点和边界半径,

var boundaryRadius = 300,
    boundaryX = 300,
    boundaryY = 300;

稍后在 ball.update 方法中我检查这些值。

    var dx = boundaryX - this.x,
        dy = boundaryY - this.y

我们需要获取球与边界中心点的距离。

        dist = Math.sqrt(dx * dx + dy * dy);

现在我们需要根据当前 Angular 获取速度

    this.radians = this.angle * Math.PI/ 180;
    this.velX = Math.cos(this.radians) * this.speed;
    this.velY = Math.sin(this.radians) * this.speed;

接下来我们检查是否仍在边界内。在这种情况下,如果我们的距离小于 300 - 我们自己的半径(即 10),即 290,则继续移动。

    if (dist < boundaryRadius-this.radius) {
        this.x += this.velX;
        this.y += this.velY;

否则,如果我们的距离大于 290,我们需要先向后移动一点,以免发生碰撞,然后我们只需更改航向 Angular 即可。您可以用更奇特的方式来实际计算您应该弹到的位置,在这个示例中,我只是将其设置为具有一点随机性的相反 Angular 。

    } else {
        this.x -= this.velX;
        this.y -= this.velY;
        this.angle += 180+Math.random()*45;
    }

fiddle screenshot

完整代码。

var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    width = 600,
    height = 600;

canvas.width = width;
canvas.height = height;

var boundaryRadius = 300,
    boundaryX = 300,
    boundaryY = 300;

var Ball = function (x, y, speed) {
    this.x = x || 0;
    this.y = y || 0;
    this.radius = 10;
    this.speed = speed || 10;
    this.color = "rgb(255,0,0)";
    this.angle = Math.random() * 360;
    this.radians = this.angle * Math.PI/ 180;
    this.velX = 0;
    this.velY = 0;
}

Ball.prototype.update = function () {
    var dx = boundaryX - this.x,
        dy = boundaryY - this.y,
        dist = Math.sqrt(dx * dx + dy * dy);

    this.radians = this.angle * Math.PI/ 180;
    this.velX = Math.cos(this.radians) * this.speed;
    this.velY = Math.sin(this.radians) * this.speed;

    // check if we are still inside of our boundary.
    if (dist < boundaryRadius-this.radius) {
        this.x += this.velX;
        this.y += this.velY;
    } else {
        // collision, step back and choose an opposite angle with a bit of randomness.
        this.x -= this.velX;
        this.y -= this.velY;
        this.angle += 180+Math.random()*45;
    }
};

Ball.prototype.render = function () {
    ctx.fillStyle = this.color;
    ctx.beginPath();
    // draw our circle with x and y being the center
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
    ctx.closePath();
    ctx.fill();

    ctx.beginPath();
    ctx.moveTo(this.x, this.y);
    ctx.lineTo(this.px, this.py);
    ctx.closePath();
};

var balls = [],
    ballNum = 10;

for(var i = 0; i < ballNum; i++){
    balls.push(new Ball(boundaryX + Math.random()*30, boundaryY + Math.random() * 30,  5 + Math.random()*15));
}


function drawAngles() {
    var d = 50; //start line at (10, 20), move 50px away at angle of 30 degrees
    var angle = 80 * Math.PI / 180;
    ctx.beginPath();
    ctx.moveTo(300, 0);
    ctx.lineTo(300, 600); //x, y
    ctx.moveTo(0, 300);
    ctx.lineTo(600, 300);
    ctx.arc(boundaryX, boundaryY, boundaryRadius, 0, 2 * Math.PI);
    ctx.strokeStyle = "#000";
    ctx.stroke();
}


function render() {
    ctx.clearRect(0, 0, width, height);
    drawAngles();

    balls.forEach(function(e){
        e.update();
        e.render();
    });

    requestAnimationFrame(render);
}

render();

关于javascript - 获取 Canvas 绘制的上下文线的边界(位置),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24319640/

相关文章:

javascript - 按下按钮时动画滚动

javascript - 计算结果向量弹跳圆/球

javascript - 使用 CSS 设置绘制到 Canvas 上的元素的样式

javascript - 从 html 表单到 javascript

javascript - 如何通过使用日期作为键对象修改此对象的结构,并将所有在同一日期完成的事件与其配对

html - 页面上的多个选项卡 - HTML CSS

javascript - 如何创建需要填写的条件字段

javascript - 在 Canvas 中绘图变得偏移

javascript - 如何从顶部显示下拉菜单使用.show()

javascript - angularjs:带有路由提供者的 Controller