九.CANVAS Math.atan和Math.atan2的区别

在cavans中,凡是涉及角度都用“弧度”表示,例如180度就应该写成Math.PI,e而360度就该写成Math.PI*2,

在实际开发中,推荐一下写法:

度数*Math.PI/180

CANVAS使用的是W3C坐标系:


三角函数公式:



Math.atan的弊端:

tan度=X/Y;

坐标轴有四个像限:

X/Y=-X/-Y

-X/Y=X/Y

这种情况会导致一个tan度对应两个角度的情况,如图(图1


tan(A)=-0.5(-1/2);

tan(B)=0.5(1/2);

tan(C)=-0.5(-1/2);

tan(D)=-0.5(-1/-2);

Math.atan无法区分26.57对应的是哪个夹角


使用Math.atan2,可以求出俩边之间夹角的度数并且判断该度数对应的是哪个夹角

Math.atan2接收两个参数,Math.atan接受的是一个参数【度数】



Math.atan2(1,2)=26.56 ,对应图1角B

Math.tan2(-1,-2)=-153.34...,对应图1角D


-153.34这个角度是从X轴正方形以逆方形计算的,这样就区分开了两个角度,如下图(图2)



由于Math.atan低弊端导致比较扫用,Math.atan2用的比较多


在线demo:http://runjs.cn/code/wsu1pqg6

源码:

绘制箭头:

function Arrow(x, y, color, angle) {
    this.x = x || 0;
    this.y = y || 0;
    this.color = color || "#FF0099";
    this.angle = angle || 0;
}
Arrow.prototype = {
    stroke: function(cxt) {
        cxt.save();
        cxt.translate(this.x, this.y);
        cxt.strokeStyle = this.color;
        cxt.beginPath();
        cxt.moveTo(-20, -10);
        cxt.lineTo(0, -10);
        cxt.lineTo(0, -20);
        cxt.lineTo(20, 0);
        cxt.lineTo(0, 20);
        cxt.lineTo(0, 10);
        cxt.lineTo(-20, 10);
        cxt.closePath();;
        cxt.stroke();
        cxt.restore();
    },
    fill: function(cxt,cnv) {

        cxt.save();
        //cnv.clearReact(cnv.width,cnv.height)
        cxt.translate(this.x, this.y);
        cxt.rotate(this.angle);
        cxt.beginPath();//切记,不要遗留这个
        cxt.moveTo(-20, -10);
        cxt.lineTo(0, -10);
        cxt.lineTo(0, -20);
        cxt.lineTo(20, 0);
        cxt.lineTo(0, 20);
        cxt.lineTo(0, 10);
        cxt.lineTo(-20, 10);
        cxt.closePath();
        cxt.fill();
        cxt.restore();

    }
}

提供鼠标位置:

window.tools = {};
window.tools.getMouse = function(element) {
    var mouse = { x: 0, y: 0 };
    element.addEventListener("mousemove", function(e) {
        var x, y;
        var e = e || window.event;
        if (e.pageX || e.pageY) {
            x = e.pageX;
            y = e.pageY;
        } else {
            //IE8以下,以及混子模式下的chrome和safari
            x = e.clientX + document.body.scrollLeft || document.documentElement.scrollLeft;
            y = e.clientY + document.body.scrollTop || document.documentElement.scrollTop;
        }
        //将当前的坐标减去canvas元素的偏移量,则为x、y为是鼠标在canvas中的相对坐标
        x -= element.offsetLeft;
        y -= element.offsetTop;
        mouse.x = x;
        mouse.y = y;
        
    });
     return mouse;
}

核心代码:

在线demo

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
    <canvas id="canvas" width="800" height="800"></canvas>
    <script src="arrow.js"></script>
    <script src="tools.js"></script>
    <script>
    function $$(id) {
        return document.getElementById(id);
    }

    window.onload = function() {
        var cnv = $$("canvas");
        var cxt = cnv.getContext('2d'); 
        //实例化一个箭筒,中心坐标为画布的中心坐标
        var arrow = new Arrow(cnv.width / 2, cnv.height / 2);

        var mouse = window.tools.getMouse(cnv);;
        function drawFrame() {
            window.requestAnimationFrame(drawFrame, cnv);
            cxt.clearRect(0, 0, 800, 800);
            //获取鼠标坐标
            var dx = mouse.x - cnv.width / 2;
            var dy = mouse.y - cnv.height / 2;
            //获取鼠标和箭头的夹角
            arrow.angle = Math.atan2(dy, dx);

            arrow.fill(cxt);
        };
        drawFrame();

    }
    </script>
</body>

</html>



  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陆康永

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值