【问题标题】:How to convert x,y coordinates to an angle?如何将x,y坐标转换为角度?
【发布时间】:2013-04-06 07:53:17
【问题描述】:

Microsoft 提供了出色的SVG gradient maker,因此 IE9 也可以具有“CSS3”渐变(单击自定义)。

我目前将他们的逻辑用于我的FireworksDreamweaver 扩展,将渐变转换为 SVG,但我只知道如何在标准的上、下、左、右方向上执行此操作。如果你输入一个角度,我不做转换,因为我不确定如何将 x1、x2、y1、y2 转换为 CSS3 角度。

梯度生成器提供如下值:x1="0%" y1="0%" x2="56.262833675564686%" y2="68.29999651227678%"

我不擅长数学或三角学,所以有人可以帮帮我吗?如果可能的话,我还想在 Sass 混合中使用相同的数学来做类似的事情。

【问题讨论】:

    标签: javascript css svg gradient trigonometry


    【解决方案1】:

    如果您从坐标中得到deltaXdeltaY,则Math.atan2 返回其参数商的反正切。返回值以弧度为单位。

    var deltaX = x2 - x1;
    var deltaY = y2 - y1;
    var rad = Math.atan2(deltaY, deltaX); // In radians
    

    然后您可以将其转换为度数,如下所示:

    var deg = rad * (180 / Math.PI)
    

    编辑

    我最初的回答中有一些错误。我相信在更新的答案中,所有的错误都得到了解决。如果您认为这里有问题,请在此处发表评论。

    【讨论】:

    • 抱歉,这对我来说毫无意义 :( Delta 是两个值之间的差?梯度生成器提供的值如下:x1="0%" y1="0%" x2="56.262833675564686% “ y2="68.29999651227678%" 我假设它不像 Math.tan((56.262833675564686-0)/(68.29999651227678-0)) 那样简单,因为这会导致 1.0798259764224096 :-\
    • deltaX 为 x2-x1,deltaY 为 y2-y1。你的答案是正确的,但是它是以弧度为单位的,你忘了乘以 (180 / Math.PI) 来得到你的答案,以度为单位
    • 你应该改用Math.atan2
    • 我看到这个答案已被编辑(它曾经说Math.tan 而不是Math.atan2),但它仍然不是完全正确。坐标的顺序应该是 (y,x) 而不是 (x,y)... 对我来说似乎也很愚蠢,但这对你来说是 JavaScript。有关Math.atan2 的文档,请参阅here 或我自己的答案以获得更多详细信息。
    • 如果我知道角度但想找出 deltaX 和 deltaY 怎么办?
    【解决方案2】:

    当前接受的答案不正确。首先,Math.tan 完全错误——我怀疑 Mohsen 的意思是 Math.atan,这只是一个错字。

    但是,作为对该答案状态的其他响应,您应该真正改用Math.atan2(y,x)。常规反正切将仅返回 -pi/2 和 pi/2(象限 1 和 4)之间的值,因为输入不明确——反正切无法知道输入值是否属于象限 1 和 3,或者2 比 4。

    另一方面,Math.atan2 可以使用给定的 xy 值来确定您所在的象限,并为所有 4 个象限中的任何坐标返回适当的角度。然后,正如其他人所指出的,如果需要,您只需乘以 (180/Math.pi) 即可将弧度转换为度数。

    【讨论】:

      【解决方案3】:

      而不是使用 Math.tan 函数你应该使用 Math.atan2:

      这是一个使用示例:

      deltaX = x2 - x1;
      deltaY = y2 - y1;
      deg = Math.atan2(deltaY, deltaX)*180.0/Math.PI;
      

      这将返回 的度数。

      【讨论】:

      • 我猜你的意思是:* (180 / Math.PI)
      • @tucson 他可以,但没关系。
      【解决方案4】:

      如果你在象限中

      P1=(X0,Y0)

      P2=(X1,Y1)

      a=(X0-X1)

      b=(Y0-Y2)

      deltaX=((a)**2)**0.5
      deltaY=((b)**2)**0.5
      rad=math.atan2(deltaY, deltaX)
      deg = rad * (360 / math.pi)
      print deg
      

      度数将在 0 ~ 180 之间

      【讨论】:

      • 这对现有答案有什么影响?
      • deltaX=((a)**2)**0.5 等价于 deltaX = a..." **2)**0.5 "互相抵消掉...有什么意义?
      • @macrocosme 我认为他想删除负值 ((-1)**2)**0.5 == 1。无论如何我认为这是一个错误的答案。
      【解决方案5】:

      var x,x1,x2,y,y1,y2;
      var cells = 'cell0';
      		var h,w;
      		var cx,cy;
      		var dx,dy;
      		var derajat;
      		var deg;
      		var ang;
      		var light;
      		var control;
      			function mouse_watch(event){
      				x = event.clientX;
      				y = event.clientY;
      				cell_data(cells);
      				koordinat(x2,y2);
      				busur(derajat);
      			}
      			function koordinat(x2,y2){
      				x2 = x-cx;
      				y2 = y-cy;
      				yk = y2;
      				xk = x2;
      			}
      			function busur(derajat){
      
      				y1 = Math.sqrt((Math.abs(yk)*Math.abs(yk))+(Math.abs(xk)*(Math.abs(xk))));
      				x1 = 0;
      				dy = yk-y1;
      				dx = xk-x1;
      				rad = Math.atan2(dy, dx);
      				derajat = rad * (360 / Math.PI);
      				cell = document.getElementById(cells);
      				ang = cell.getElementsByClassName('angle0')[0];
      				ang.style.transform = 'rotate('+derajat+'deg)';
      				light = ang.getElementsByClassName('points')[0];
      				light.style.height = y1+'px';
      			}
      			function cell_data(cells){
      				cell = document.getElementById(cells);
      				h = Number(cell.style.height.replace('px',''));
      				w = Number(cell.style.width.replace('px',''));
      				cy = Number(cell.style.top.replace('px',''))+h/2;
      				cx = Number(cell.style.left.replace('px',''))+w/2;
      			}
      			.preview_engine{
      				position: absolute;
      				top: 0;
      				left: 0;
      				padding: 10px;
      				background-color: #2E8AE6;
      				color: white;
      			}
      			body{
      				cursor: default;
      				width: 100%;
      				height: 100%;
      				font-family: Arial;
      				font-size: 12px;
      			}
      			.fieldwork{
      				width: 100%;
      				height: 100%;
      				position: absolute;
      				top: 0px;
      				left: 0px;
      			}
      			.cell{
      				position: relative;
      				transition : width 2s, height 2s, top 2s, left 2s;
      				background-color: red;
      			}
      			.angle0{
      				width: 200px;
      				height: 200px;
      				position: absolute;
      				top: -75px;
      				left: -75px;
      				background-color: green;
      				border-radius: 50%;
      				opacity: 0.5;
      				transition : width 2s, height 2s, top 2s, left 2s;
      			}
      			.points{
      				width: 10px;
      				height: 10px;
      				position: absolute;
      				left: 95px;
      				top: 95px;
      				background-color: red;
      				border-radius: 1em;
      				opacity: none;
      			}
      <div class="fieldwork" onmousemove="mouse_watch(event)">
      <div class='cell' id="cell0" style="width:50px;height:50px;top:200px;left:400px;">
      <div class="angle0">
      <div class="points"></div>
      </div>
      </div>
      </div>

      【讨论】:

      • 虽然这是一个不错的小部件,但这并没有为任何答案添加任何内容......也没有回答问题......
      • “每个答案的代码量随着 stackoverflow 问题的答案数量的增加而增加”(“so-ed-1”-theorem)。 “代码质量随着 stackoverflow 问题的答案数量而降低”(“so-ed-2”-theorem)-对不起我的讽刺
      【解决方案6】:

      此函数接受 2 个元素并返回元素中间的度数。

      例如,我在世界地图上使用它,使平面图像沿城市方向旋转。

      function degFromTwoElements(el1,el2){
          var x1,x2,y1,y2,cx1,xy1,cx2,cy2,deltaX,deltaY,dx,dy,rad,deg,shortest,number;
          x1 = el1.position().left;
          y1 = el1.position().top;
          x2 = el2.position().left;
          y2 = el2.position().top;
          cx1 = x1 - (el1.width() / 2);
          cy1 = y1 - (el1.height() / 2);
          cx2 = x2 - (el2.width() / 2);
          cy2 = y2 - (el2.height() / 2);
      
          deltaX = cx2 - cx1;
          deltaY = cy2 - cy1;
          y1 = Math.sqrt((Math.abs(deltaY)*Math.abs(deltaY))+(Math.abs(deltaX)*(Math.abs(deltaX))));
          x1 = 0;
          dy = deltaY-y1;
          dx = deltaX-x1;
          rad = Math.atan2(dy, dx);
          deg = rad * (360 / Math.PI);
      
          shortest;
          number = Math.abs(deg);
          if ((360 - number ) < number){
              shortest = 360 - number;
              console.log('shorter degree: ' + shortest);
              return shortest;
          } 
          else console.log('Angle is: ' + deg);
          return deg;
      
      }
      

      【讨论】:

      • 跟问题无关。
      • 应该是 (180 / Math.PI);
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-07
      相关资源
      最近更新 更多