计算45度捕捉的坐标 [英] Calculate coordinates for 45 degree snap

查看:123
本文介绍了计算45度捕捉的坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个SVG,它在原点和鼠标指针之间画一条线,我想做的就是当按下shift键时(event.shiftKey === true)使那条线"snap"最接近45度坐标,基本上与您在photoshop中获得的行为相同.

I have a SVG that draws a line between an origin point and the mouse pointer, what i'd like to do is when shift is depressed (event.shiftKey === true) make the line "snap" to the nearest 45 degree coordinate, the same behaviour you get in photoshop basically.

我设法计算出两点之间的角度(因此我也可以决定要捕捉哪个角度,如果需要的话,可以使用IF/ELSE树),但是我不知道如何重新设置角度.根据新的度数计算结束"坐标.

I've managed to work out the angle in degrees between the two points (so i can decide which angle to snap too, probably using an IF/ELSE tree if needs be) however I don't know how i re-calculate the "end" coordinates based on the new degree's.

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

I've set up a simplified example here: https://jsbin.com/sohafekije/2/edit?html,js,output

我还拍了一张我试图重新创建的photoshop行为照片(质量很差,因为我不得不使用相机,因为我无法截图-抱歉),请务必100%清除: http://i.imgur.com/Yo04uxY.jpg

I've also taken a photo of the photoshop behaviour i'm trying to recreate (quality is poor as i had to use a camera as i couldn't screenshot - sorry) just to be 100% clear: http://i.imgur.com/Yo04uxY.jpg

本质上来说,我想重新创建当您按住Shift键时在photoshop中得到的行为,但是我猜想您需要对Maths相当了解才能找到解决方案,而我不是!

Essentially i'm trying to recreate the behaviour you get in photoshop when you hold the shift key, but my guess is you need to be pretty good with Maths to work out a solution, and i'm not!

非常感谢您的帮助:)

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>

推荐答案

我做到了!

如何使用

您可以计算新角度,并使用余弦表示x值,使用正弦表示y值.这里角度以PI/4为步长到-PI到PI.如果要更改步骤,请用其他数字替换"var newAngle = ..."行中的4.

You compute the new angle and apply it using cosinus for x value and sinus for y value. Here the angle got to -PI to PI with step of PI/4; If you want to change the step replace 4 in the line 'var newAngle = ...' by other number.

它是如何工作的

How it's works

首先,我在考虑以下事实:您需要8个角度位置,PI rad为4(角度为2PI rad).因此,您需要简化角度.

First I was thinking about the fact that you need 8 angle position, 4 by PI rad (a cirlce is 2PI rad). So you need to simplify your angle.

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乘以长度,您可以找到下一个点.

Now your new angle is correct. Cosinus return the x value of the angle (look at wikipedia for a graphic explanation) and Sinus the y value of the angle. By multiplying the COSINUS/SINUS by the length you find the next point.  

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)];
}

这篇关于计算45度捕捉的坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆