SVG在路径上查找点到x轴的方向(角度)

Posted

技术标签:

【中文标题】SVG在路径上查找点到x轴的方向(角度)【英文标题】:SVG find orientation(angle) of a point to the x axis on a path 【发布时间】:2015-12-23 15:54:03 【问题描述】:

我通过在路径上移动一个对象来制作视差,它与getPointAtlength() 一起工作正常,但我还需要随着路径旋转这个对象。

我需要像getPointAtLength() 这样的东西,但对于我得到点的角度的角度。 Rapheal 似乎有一种方法,但它对在 html 中创建的 svg 元素不友好,或者我不知道如何处理它。有什么想法吗?

var l = document.getElementById('path');
var element=$('#svg_26')
$(window).scroll(function()
    var pathOffset=parseInt($('#l1').css('stroke-dashoffset'));
    var p = l.getPointAtLength(-1*pathOffset);
    translation = 'translate('+p.x+'px,'+p.y+'px)'
    $(element).css('transform',translation);
)

【问题讨论】:

创建小提琴,会有帮助的! 【参考方案1】:

Raphael 中的 getPointAtLength 返回一个具有“alpha”属性的对象。 Alpha 是沿曲线所需的角度。在上面的示例中,它将是 p.alpha

所以你应该能够对被 p.alpha 旋转的对象应用旋转,

例如..

myRaphElement.transform('t' + p.x + ',' + p.y + 'r' + p.alpha)。

最后一部分将围绕其中心旋转元素。

如果您无法创建 raph 元素本身,因为 svg 是内联的,我怀疑您最好使用 Snap.svg 之类的库(与同一作者的命令几乎相同),或者您可以动态使用类似'rotate('+l.alpha+','+l.x+','+l.y+')'之类的css变换来旋转

编辑:当它没有被使用时,我误读了,因为标签中有 Raphael。

我个人会在这种情况下使用 Snap,因为 Raphael 在这里没有添加太多内容。您可以在屏幕外创建一个 Raphael 元素,其路径与内联元素相同,只是为了使用角度,但为此加载库感觉有点过头了。

在 Snap 中,您可以使用...访问元素。

myElement = Snap('#svg_26')
p = myElement.getPointAtLength(-1*pathOffset);    
myElement.transform('t' + p.x + ',' + p.y + 'r' + p.alpha)

【讨论】:

但我的元素不是 raphael,它们是 html 中 SVG 标记中的普通元素 试过 Raphael.getPointAtLength(l,offset) 但给了我 NaNs 如果你纯粹使用内联,那么我认为 Raphael 是不适合这项工作的工具,试试 Snap.svg。相同的答案将适用,因为它适用于内联 svg。【参考方案2】:

使用库来完成此类任务将是矫枉过正。编写自己的函数来计算角度实际上非常简单。您所要做的就是使用 pointAtLength 两次并稍微偏移:

var p1 = path.getPointAtLength(l)
var p2 = path.getPointAtLength(l + 3)

然后使用 Math.atan2 计算结果线与 x 轴的角度

var deg = Math.atan2(p1.y - p2.y, p1.x - p2.x) * (180 / Math.PI);

这是一个使用上述公式的小例子

var path = document.getElementById("path")
var obj = document.getElementById("obj")
var l = 0
var tl = path.getTotalLength()

function getPointAtLengthWithRotation(path, length) 
  var p1 = path.getPointAtLength(length)
  var p2 = path.getPointAtLength(length + 3)
  var deg = Math.atan2(p1.y - p2.y, p1.x - p2.x) * (180 / Math.PI);
  return 
    x: p1.x,
    y: p1.y,
    angle: deg
  


setInterval(function() 
  l += 1
  if (l > tl) l = 0;
  var p = getPointAtLengthWithRotation(path, l)
  obj.setAttribute("transform", "translate(" + p.x + "," + p.y + ") rotate(" + (p.angle + 180) + ")")
, 30)
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"  >
  <path id="path" d="M 81.713425,82.629068 C 77.692791,85.788547 73.298237,77.367896 68.194886,79.039107 63.091534,80.710434 58.027628,96.952068 53.04637,97.140958 48.065112,97.329732 50.503508,75.285207 45.397105,74.05952 40.290703,72.833834 38.487501,93.968537 33.85932,91.287114 29.23114,88.605807 32.245641,70.914733 29.647307,66.19971 27.048973,61.484686 19.604932,68.733636 17.542589,63.315055 15.480245,57.896474 32.172733,59.004979 32.053727,53.363216 31.93472,47.721442 8.0865997,39.989401 9.2246856,34.665848 10.362772,29.342295 28.830448,38.693055 31.065274,33.7132 33.300101,28.733334 22.734045,13.601966 26.210126,9.6067771 29.686208,5.6115765 41.809938,29.357138 46.524268,27.383715 c 4.71433,-1.973424 3.011846,-23.1001292 8.022646,-23.3332919 5.0108,-0.2331744 4.529056,18.3713929 9.45006,20.4259809 4.921003,2.054588 12.017373,-15.4803016 16.717604,-13.058602 4.700233,2.421699 -6.261038,14.180819 -2.913997,18.778859 3.347041,4.59804 12.339067,-3.78046 13.896719,1.543011 1.557652,5.323471 -9.713912,13.199372 -9.176986,18.679109 0.536926,5.479772 19.347976,2.957331 18.124596,8.213665 -1.223374,5.256392 -21.036293,1.236997 -24.253076,5.968111 -3.216785,4.731114 9.342224,14.869033 5.321591,18.028511 z"
  fill="none" stroke="grey" />
  <path id="obj" d="M-5 -5 L5 0L-5 5z" fill="green" />
</svg>

【讨论】:

以上是关于SVG在路径上查找点到x轴的方向(角度)的主要内容,如果未能解决你的问题,请参考以下文章

c语言编写点到原点的距离以及与x轴正方向的角度

查找 2 条折线之间的角度

WebGL常用数学公式

2022-04-30:在无限的平面上,机器人最初位于 (0, 0) 处,面朝北方。注意: 北方向 是y轴的正方向。 南方向 是y轴的负方向。 东方向 是x轴的正方向。 西方向 是x轴的负方向。 机器人

在 ARFaceTracking 会话中从 ARFaceAnchor 查找头部倾斜角度

SVG Path标签 A 参数