javascript - 计算 45 度捕捉的坐标

标签 javascript math svg svg.js

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

我已经设法计算出两点之间的 Angular (这样我也可以决定捕捉哪个 Angular ,如果需要的话可能使用 IF/ELSE 树),但是我不知道如何重新-根据新度数计算“结束”坐标。

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

我还拍了一张我试图重现的 Photoshop 行为的照片(质量很差,因为我无法截图,所以我不得不使用相机 - 抱歉),只是为了 100% 清晰:/image/9r2MN.jpg

enter image description here

本质上,我试图重现你在 Photoshop 中按住 Shift 键时的行为,但我猜你需要非常擅长数学才能找到解决方案,而我不是!

非常感谢任何帮助:)

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>

最佳答案

我做到了!

How use it

您计算新 Angular 并使用余弦作为 x 值,使用正弦作为 y 值来应用它。这里 Angular 从 -PI 到 PI,步长为 PI/4;如果您想更改步骤,请将“var newAngle = ...”行中的 4 替换为其他数字。

How it's works

首先,我想到了这样一个事实:您需要 8 个 Angular 位置,其中 4 个按 PI 弧度(一个圆为 2PI 弧度)。所以你需要简化你的 Angular 。

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)

现在你的新 Angular 是正确的。余弦返回 Angular x 值(有关图形解释,请参阅维基百科),而正弦返回 Angular y 值。 通过将余弦/正弦乘以长度,您可以找到下一个点。

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

关于javascript - 计算 45 度捕捉的坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42510144/

相关文章:

javascript - 为什么这个简单的过滤器返回一个空数组?

java - FFT窗口大小的意义

html - 按钮内的 svg 覆盖文本,但我需要它在按钮内 float

CSS3 SVG 动画在 Safari 中不起作用

javascript - v-for 取决于标签

javascript - 调整文本大小的纯 Javascript 算法

actionscript-3 - AS3 笛卡尔坐标的极坐标

html - SVG 在 IE 中无法正确缩放 - 有额外的空间

JavaScript 字符串生成器不工作

css - 如何使用由三重 RGB 值定义的色带计算新的类似颜色渐变?