试图找到两个向量之间的角度(三角形)(HTML5 Canvas)

Posted

技术标签:

【中文标题】试图找到两个向量之间的角度(三角形)(HTML5 Canvas)【英文标题】:Trying to find angle between two vectors (triangle) (HTML5 Canvas) 【发布时间】:2012-11-02 04:43:39 【问题描述】:

如果绘制的不是直角,我很难理解为什么我的角度会返回奇怪的角度。我在 html5 中使用 Canvas 绘制了一个基本三角形。

我有 html 代码和 js 代码要粘贴在这里:请有人告诉我为什么只有这些直角加起来是 180 度。我已经设置了js代码将角度及其总和输出到控制台......所以你可以看到我在说什么。

你可以修改draw函数代码,设置其中一个点的位置成直角..然后你会看到180度,角度是正确的。

我在整个互联网上搜索了一个解释并检查了我的公式。似乎无法弄清楚这一点。

非常感谢您提供的任何帮助..

--- HTML 代码 ---

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Canvas - Triangle experiment</title>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
    <script src="js/drawShapes.js"></script>
    <style>
        *  margin: 0; 
        *  padding: 0; 

        span.markings 
            position: absolute;
        

        div.drawingArea 
            margin: 50px 0 0 10px;
            padding: 0;
            width: 500px;
            height: 500px;
            position: relative;
            background: #ccc;
        
        .coords  position: absolute; top: 0; left: 200px; 
        .coords p  position: relative; 
        .xcoord, .ycoord   font-weight: bold; color: red; 
        #myCanvas  background: #eee; 
    </style>
  </head>
  <body>
    <div class="coords"><p>X: <span class="xcoord"></span></p><p>Y: <span class="ycoord"></span></p></div>
    <div class="drawingArea">
        <span class="markings A"></span>
        <span class="markings B"></span>
        <span class="markings C"></span>
        <canvas id="myCanvas"  >Your browser does not have support for Canvas. You should see:</canvas>
    </div>
  </body>
</html>

--- JS 代码---

$(document).ready(function()
    // Just for dev purposes.. show X and Y coords when inside drawingArea
    $('.drawingArea').mousemove(function(e)
        $('.xcoord').html(e.pageX -10); // subtract 10 for margin left is 10
        $('.ycoord').html(e.pageY -50); // subtract 40 bc margin top is 40
    );

    draw();

    function draw()
    
        // Initialize context
        createContext('2d');

        // Set the style properties.
        context.fillStyle   = '#fff';
        context.strokeStyle = '#FF9900';
        context.lineWidth   = 5;

        // Set initial positions and lengths
        pts = ;
        pts.AXLoc = 60;
        pts.AYLoc = 40;
        pts.BXLoc = 360;
        pts.BYLoc = 40;
        pts.CXLoc = 100;
        pts.CYLoc = 340;

        // Get difference between points
        vector = ;
        vector.Ax = Math.abs(pts.AXLoc-pts.BXLoc);
        vector.Ay = Math.abs(pts.AYLoc-pts.BYLoc);
        vector.Bx = Math.abs(pts.BXLoc-pts.CXLoc);
        vector.By = Math.abs(pts.BYLoc-pts.CYLoc);
        vector.Cx = Math.abs(pts.CXLoc-pts.AXLoc);
        vector.Cy = Math.abs(pts.CYLoc-pts.AYLoc);

        console.log(vector.Ax);
        console.log(vector.Ay);
        console.log(vector.Bx);
        console.log(vector.By);
        console.log(vector.Cx);
        console.log(vector.Cy);

        // Find the magnitude of each vector
        vector.magA = Math.sqrt(Math.pow(vector.Ax, 2) + Math.pow(vector.Ay, 2));
        vector.magB = Math.sqrt((Math.pow((vector.Bx), 2) + Math.pow((vector.By), 2)));
        vector.magC = Math.sqrt((Math.pow((vector.Cx), 2) + Math.pow((vector.Cy), 2)));

        // Cos A = (A.C) / sqrt(magnitude of A) x (magnited of C)
        // This should return radian which is then converted to degrees
        // Create function once code works!
        vector.angleA = ((vector.Ax * vector.Cx) + (vector.Ay * vector.Cy)) / (vector.magA * vector.magC); 
        vector.angleA = Math.acos(vector.angleA) * (180/Math.PI);
        vector.angleB = ((vector.Ax * vector.Bx) + (vector.Ay * vector.By)) / (vector.magA * vector.magB); 
        vector.angleB = Math.acos(vector.angleB) * (180/Math.PI);
        vector.angleC = ((vector.Bx * vector.Cx) + (vector.By * vector.Cy)) / (vector.magB * vector.magC); 
        vector.angleC = Math.acos(vector.angleC) * (180/Math.PI);


        // Output test data         
        console.log('angle a = ' + vector.angleA);
        console.log('angle b = ' + vector.angleB);
        console.log('angle c = ' + vector.angleC);
        vector.allangles = vector.angleA + vector.angleB + vector.angleC;
        console.log('All angles = ' +vector.allangles ); // only adds up to 180deg if right angle??!!

        // Begin drawing
        context.beginPath();
        // Start from the top-left point.
        context.moveTo(pts.AXLoc, pts.AYLoc); // give the (x,y) coordinates
        context.lineTo(pts.BXLoc, pts.BYLoc);
        context.lineTo(pts.CXLoc, pts.CYLoc);
        //context.lineTo(pts.AXLoc, pts.AYLoc); // closes the origin point? alternate way of closing???
        context.lineJoin = 'mitre';
        context.closePath(); // closes the origin point? good for strokes

        // Done! Now fill the shape, and draw the stroke.
        // Note: your shape will not be visible until you call any of the two methods.
        context.fill();
        context.stroke();
        context.closePath();

        // Set position of markings (spans)
        $('span.markings.A').css(
                'top'   : pts.AYLoc -30,
                'left'  : pts.AXLoc -5
            );

        $('span.markings.B').css(
                'top'   : pts.BYLoc -5,
                'left'  : pts.BXLoc +10
            );

        $('span.markings.C').css(
                'top'   : pts.CYLoc -5,
                'left'  : pts.CXLoc -25
            );

        // Write markings onto canvas (degrees and lengths) 
        $('span.markings.A').html('A');  
        $('span.markings.B').html('B');  
        $('span.markings.C').html('C');         
    

    function createContext(contextType)
    
        // Get the canvas element.
        var elem = document.getElementById('myCanvas');
        if (!elem || !elem.getContext) 
        return;
        

        // Get the canvas 2d context.
        context = elem.getContext(contextType);
        if (!context) 
        return;
        
    
);

【问题讨论】:

【参考方案1】:

你的角度公式有点错误。这是一个有效的小提琴:http://jsfiddle.net/manishie/AgmF4/。

这是我更正后的公式:

    vector.angleA = (Math.pow(vector.magB, 2) + Math.pow(vector.magC, 2) - Math.pow(vector.magA, 2)) / (2 * vector.magB * vector.magC);
    vector.angleA = Math.acos(vector.angleA) * (180/Math.PI);

    vector.angleB = (Math.pow(vector.magA, 2) + Math.pow(vector.magC, 2) - Math.pow(vector.magB, 2)) / (2 * vector.magA * vector.magC);
    vector.angleB = Math.acos(vector.angleB) * (180/Math.PI);

    vector.angleC = (Math.pow(vector.magA, 2) + Math.pow(vector.magB, 2) - Math.pow(vector.magC, 2)) / (2 * vector.magA * vector.magB);
    vector.angleC = Math.acos(vector.angleC) * (180/Math.PI);

【讨论】:

Manishie,所以我有点困惑......这是我习惯于这封信的公式,所以不确定你是如何得出你的。尽管如此,我还是欠你的。非常感谢。 youtube.com/watch?v=4WxniMJYySc&feature=plcp 没问题! :-) 我从 25 年前的一本旧数学书中得到了解决方案!

以上是关于试图找到两个向量之间的角度(三角形)(HTML5 Canvas)的主要内容,如果未能解决你的问题,请参考以下文章

余弦距离

相似性度量(转)

计算几何学习7

如何找到距离等于 X 的两个向量的点

Matlab - 如何对两个矩阵之间的每一行执行操作?

三角学,向量,矩阵和四元数(上)