首页 > 解决方案 > 如何用 SVG 弧线为指南针的 8 个方向绘制 1/4 弧线?

问题描述

如何从 8 个不同的方向开始画一个弧,然后画一个 1/4 的圆?就像指南针一样。我已经尝试了大约一个小时的每种组合,试图让它成为一个弧形,就像一个带有尾巴的“r”的开始,但我无法让它发挥作用。我想看看它是如何在各个方向上完成的,这样我就可以更好地了解如何操作它。

function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
  var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;

  return {
    x: centerX + (radius * Math.cos(angleInRadians)),
    y: centerY + (radius * Math.sin(angleInRadians))
  };
}

console.log(describeArc(0, 250, 25, -90, 0))

function describeArc(x, y, radius, startAngle, endAngle){
  var start = polarToCartesian(x, y, radius, endAngle);
  var end = polarToCartesian(x, y, radius, startAngle);

  var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";

  var d = [
      "M", start.x, start.y,
      "A", radius, radius, 0, largeArcFlag, 0, end.x, end.y
  ].join(" ");

  return d;
}
path {
  float: left;
  stroke-linecap: round;
}
<svg style="display: inline-block; width: 50px; height: 250px" viewBox="-20 -20 120 520" xmlns="http://www.w3.org/2000/svg">
  <g>
    <path d="
      M 0 300
      l 0 -50
      M 0 225 A 25 25 0 0 0 -25 275"
      fill="none" stroke="#000" stroke-width="10px" />
  </g>
</svg>

我得到了这个功能,但似乎没有按我的预期工作。

标签: javascriptsvggeometry

解决方案


您的函数 polarToCartesian 正在将极坐标转换为笛卡尔坐标。
我不认为这是你想要的,但你会在 console.log 中为 startAngle、endAngle 放置以下参数集

0, 45 | 45, 90 | 90, 135 | 135, 180 | 180, 225 | 225, 270 | 270, 315 | 315、360 |。

x 和 y 参数需要再次计算为笛卡尔坐标空间中的不同坐标。这些取决于您的第一个坐标开始的位置。绘制任何依赖于绕圈的东西,你需要考虑圆圈的中心在哪里。圆心的坐标最好描述为 0、0,然后将圆移动到所需位置。坐标取决于半径,你有 25。所以我建议:

0, -25 | 17.677, -17.677 | 25, 0 | 17.677, 17.677 | 0, 25 | -17.677, 17.677 | -25, 0 | -17.677, 17.677

17.677 由 a² + b² = c² 的毕达哥拉斯定理获得。

如果你知道半径,因为直角三角形可以从半径(作为斜边)组成,你会得到一个边相等的三角形,斜边为 45°。
所以相等边之一的长度是√(c² / 2)。

function equalSideLength(radius){
                                 return Math.sqrt(Math.pow(radius, 2)/2);
}

为了说明输出示例,首先只显示四分之一,然后是圆的八分之一,我建议以下计划并根据需要添加笔画属性并将填充设置为无(添加空格以提高可读性并添加比例以查看它!) . 并且不要忘记将整个绘图翻译到您需要的位置。

<svg width="1000" height="1000">
  <g transform="translate(100 100) scale(50)">
    <path d="M0 0 L 0 -2 A2 2 0 0 1  2  0 " fill="red"/>
    <path d="M0 0 L 2  0 A2 2 0 0 1  0  2" fill="yellow"/>
    <path d="M0 0 L 0  2 A2 2 0 0 1 -2  0" fill="pink"/>
    <path d="M0 0 L-2  0 A2 2 0 0 1  0 -2" fill="green"/>
  </g>
  
  <g transform="translate(400 100) scale(50)">
    <path d="M0 0 L 0   -2   A2 2 0 0 1  1.4  -1.4" fill="red"/>
    <path d="M0 0 L 1.4 -1.4 A2 2 0 0 1  2     0  " fill="yellow"/>
    <path d="M0 0 L 2    0   A2 2 0 0 1  1.4   1.4" fill="pink"/>
    <path d="M0 0 L 1.4  1.4 A2 2 0 0 1  0     2  " fill="green"/>
    <path d="M0 0 L 0    2   A2 2 0 0 1 -1.4   1.4" fill="orange"/>
    <path d="M0 0 L-1.4  1.4 A2 2 0 0 1 -2     0  " fill="purple"/>
    <path d="M0 0 L-2    0   A2 2 0 0 1 -1.4  -1.4" fill="blue"/>
    <path d="M0 0 L-1.4 -1.4 A2 2 0 0 1  0    -2  " fill="grey"/>
   </g>
<svg>


推荐阅读