简体   繁体   中英

Collision detection of two arcs in html5 canvas

I am trying to detect if two balls are intersecting on a HTML5 canvas. I need a function called intersect as a part of a constructor object called Ball. This function will take one Ball object as an argument and return true if the two balls on the canvas are touching/ intersecting. and false otherwise.

I cant figure out how to pass in a new instance of a ball to the intersect function and then compare it to another ball on the canvas. The function I'm working on the is the final function intersect at the end of the Ball Object. Please see below for the code i have so far.

Any help would be greatly appreciated.

<!DOCTYPE html>
<hmtl>
  <head>
    <meta charset="UTF-8">
    <title>Canvas</title>
    <style type="text/css">
    canvas{
    border: 1px solid black;
    }
    </style>

  </head>

  <body>

    <canvas id="canvasOne" ></canvas>


    <script type="text/javascript">
        // Gets a handle to the element with id canvasOne.
        var canvas = document.getElementById("canvasOne");

        // Set the canvas up for drawing in 2D.
        var ctx = canvas.getContext("2d");  
        canvas.width  = 500;
        canvas.height = 500;

    function Ball(xpos,ypos,r) {
        this.xpos = xpos;
        this.ypos = ypos;
        this.r = r;
        this.move =  function(addx,addy){
            this.xpos = this.xpos + addx;
            this.ypos = this.ypos + addy;
        };
        this.resize =  function(setr){
            this.r = setr;
        };


        this.draw = function(){ 

            for (var i = 0; i < 7; i++) {
                ctx.beginPath();
                ctx.moveTo(ball.xpos, ball.ypos);
                ctx.arc(ball.xpos, ball.ypos, ball.r, i*(2 * Math.PI / 7), (i+1)*(2 * Math.PI / 7));                    
                ctx.lineWidth = 2;
                ctx.strokeStyle = '#444';
                ctx.stroke();
            }

            ctx.beginPath();
            ctx.moveTo(ball.xpos, ball.ypos);
            ctx.arc(ball.xpos,ball.ypos,ball.r-10,0,2*Math.PI);
            ctx.lineWidth = 2;
            ctx.strokeStyle = '#444';
            ctx.stroke();

        };
        this.rotate = function(){
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            // Move registration point to the center of the canvas
            ctx.translate(ball.xpos, ball.ypos);

            // Rotate 1 degree
            ctx.rotate(Math.PI / 180);

            // Move registration point back to the top left corner of canvas
            ctx.translate(-ball.xpos, -ball.ypos);

            ball.draw();

            ctx.restore();

        };
        this.contains = function(x, y){
            this.x = this.x;
            this.y = this.y;
            if(Math.sqrt((x-ball.xpos)*(x-ball.xpos) + (y-ball.ypos)*(y-ball.ypos)) <= ball.r)
            {
                return true;
            }else{
                return false;
            }
        };

        this.intersect = function(){
            this.ball1 = this.ball1;

            var distance = (ball.xpos * ball.xpos) + (ball.ypos *ball.ypos);
            if(distance <= (ball.r + ball.r)*(ball.r + ball.r)){
                return true;
            }else{
                return false;
            }

        };

    }

    var  ball = new Ball(100,100,100);
    ball.draw();




    </script>

  </body>

</html>

I cant figure out how to pass in a new instance of a ball to the intersect function

Well to pass anything really it should have an argument.

this.intersect = function(otherball){
 // then compare the two ball objects

Then...

var ball1 = new Ball(100,100,100);
var ball2 = new Ball(100,100,100);
ball1.draw();
ball2.draw();

console.log(ball1.intersect(ball2));

First off, if you aren't going to use the this keyword in your class, then why make it a class?

You can setup your intersect to take a Ball as a parameter. From here you can calculate the collision between this and the parameter Ball .

You distance function was off, as it only looked on the this object, and i fixed the this problem in your code:

 var canvas = document.body.appendChild(document.createElement("canvas")); // Set the canvas up for drawing in 2D. var ctx = canvas.getContext("2d"); canvas.width = 500; canvas.height = 500; function Ball(xpos, ypos, r) { this.xpos = xpos; this.ypos = ypos; this.r = r; this.move = function(addx, addy) { this.xpos = this.xpos + addx; this.ypos = this.ypos + addy; }; this.resize = function(setr) { this.r = setr; }; this.draw = function() { for (var i = 0; i < 7; i++) { ctx.beginPath(); ctx.moveTo(this.xpos, this.ypos); ctx.arc(this.xpos, this.ypos, this.r, i * (2 * Math.PI / 7), (i + 1) * (2 * Math.PI / 7)); ctx.lineWidth = 2; ctx.stroke(); } ctx.beginPath(); ctx.moveTo(this.xpos, this.ypos); ctx.arc(this.xpos, this.ypos, this.r - 10, 0, 2 * Math.PI); ctx.lineWidth = 2; ctx.stroke(); }; this.rotate = function() { ctx.clearRect(0, 0, canvas.width, canvas.height); // Move registration point to the center of the canvas ctx.translate(this.xpos, this.ypos); // Rotate 1 degree ctx.rotate(Math.PI / 180); // Move registration point back to the top left corner of canvas ctx.translate(-this.xpos, -this.ypos); this.draw(); ctx.restore(); }; this.contains = function(x, y) { this.x = this.x; this.y = this.y; if (Math.sqrt((x - this.xpos) * (x - this.xpos) + (y - this.ypos) * (y - this.ypos)) <= this.r) { return true; } else { return false; } }; //put "ball" as a paremeter //ball will be the foreign Ball to test intersection against this.intersect = function(ball) { var productX = this.xpos - ball.xpos; var productY = this.ypos - ball.ypos; var distance = Math.sqrt(productX * productX + productY * productY); if (distance <= (this.r + ball.r)) { return true; } else { return false; } }; } var ball1 = new Ball(100, 100, 100); var ball2 = new Ball(240, 140, 40); function update(evt) { ctx.clearRect(0, 0, canvas.width, canvas.height); if (evt !== void 0) { ball2.xpos = evt.offsetX; ball2.ypos = evt.offsetY; } //Pass the ball as an argument to the method ctx.strokeStyle = ball1.intersect(ball2) ? "red" : '#444'; ball1.draw(); ball2.draw(); } update(); canvas.onmousemove = update; 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM