计算45度快照的坐标

时间:2017-02-28 13:30:43

标签: javascript math svg svg.js

我有一个在原点和鼠标指针之间画一条线的SVG,我想做的是当按下shift时(event.shiftKey === true)使线条“快速”到最近45度坐标,基本上与你在photoshop中获得的行为相同。

我已经设法计算出两点之间的角度(所以我可以决定要捕捉哪个角度,如果需要可能使用IF / ELSE树)但是我不知道我是怎么回事根据新学位计算“结束”坐标。

我在这里设置了一个简化示例:https://jsbin.com/sohafekije/2/edit?html,js,output

我还拍了一张我试图重新创建的photoshop行为的照片(质量差,因为我不得不使用相机,因为我无法截图 - 抱歉)只是为了100%清晰:{{3 }}

http://i.imgur.com/Yo04uxY.jpg

基本上我正在尝试重新设置当你按住shift键时你在photoshop中获得的行为,但我的猜测是你需要很好地使用Maths来制定解决方案,而我不是!

非常感谢任何帮助:)

var app = document.getElementById('app'),
    svg = SVG(app),
    line = svg.polyline([]).fill('none').stroke({ width: 1 }),
    start = [250,250],
    end = null,
    angleTxt = document.getElementById('angle'),
    lineLengthTxt = document.getElementById('linelength');

line.marker('start', 10, 10, function(add) {
  add.circle(10).fill('#f06')
})

// On mouse move, redraw the line
svg.on('mousemove', function(e){
  end = [e.layerX, e.layerY];
  line.plot([start, end]);
  calcAngle();
});

function calcAngle() {
  var deltaX = end[0] - start[0],
      deltaY = end[1] - start[1],
      rad = Math.atan2(deltaY, deltaX),
      deg = rad * (180/Math.PI),
      linelen = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
  

  
  angleTxt.textContent = deg;
  lineLengthTxt.textContent = linelen;
  
}
#app { border: 1px solid blue; width:100%; height:600px}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <script type="text/javascript" src="https://rawgit.com/svgdotjs/svg.js/master/dist/svg.js"></script>
</head>
<body>
  <div id="app"></div>
  Angle: <span id="angle">-</span><br>
  Line Length: <span id="linelength">-</span>
</body>
</html>

1 个答案:

答案 0 :(得分:2)

我做到了!

  

如何使用

您计算新角度并使用cosinus将其应用于x值,将sin应用于y值。这里角度达到-PI到PI,步长为PI / 4;如果您想更改“var newAngle = ...”行中的步骤替换为其他数字。

  

它是如何运作的

首先,我考虑的事实是你需要8个角度位置,4个PI rad(cirlce是2PI rad)。所以你需要简化你的角度。

newAngle / Math.PI // value is between -1 and 1 (it's a double)
newAngle / Math.PI * 4 // value is between -4 and 4 (it's a double)
Math.round(newAngle / Math.PI * 4) // value is between -4 and 4 (but it's a integer now)
Math.round(newAngle / Math.PI * 4) / 4 // value is between -1 and 1 (with step of 0.25)
Math.round(newAngle / Math.PI * 4) / 4 * Math.PI // value is between -PI and PI with step of 0.25 * PI (PI/4)

现在你的新角度是正确的。 Cosinus返回角度的x值(查看维基百科的图形说明)和Sinus角度的y值。 通过将COSINUS / SINUS乘以您找到下一个点的长度。

function applyNewAngle() {
  var deltaX = end[0] - start[0],
      deltaY = end[1] - start[1],
      dist = Math.sqrt(Math.pow(deltaX,2) + Math.pow(deltaY,2));
  var newAngle = Math.atan2(deltaY, deltaX);
  var shiftedAngle = Math.round(newAngle / Math.PI * 4) / 4 * Math.PI;
  end = [start[0]+dist*Math.cos(shiftedAngle), start[1]+dist*Math.sin(shiftedAngle)];
}