svg - 在 SVG 上绘制圆的一段

标签 svg automatic-ref-counting geometry

鉴于以下信息:

  • 白点是圆的中心。
  • 蓝色、绿色点是圆边界上的点。
  • 方向:顺时针、逆时针

使用任何点(蓝色,绿色)和白点,然后我可以得到半径并可以画一个圆。但是我不想画一个圆,而只是蓝点和绿点之间的圆弧

将 arc 与 SVG(椭圆)结合使用,我得到 2 个带有 large_arc_flag 的选项

enter image description here

enter image description here

在这个例子中:第二个选项是我想要的:large_arc_flag=1,但有时我想要large_arc_flag=0。事实上,我只想要属于该圆的弧线。使用带有“A”的路径,由于椭圆的相交,我有 2 条弧可供选择。

我该如何解决这个问题?

谢谢!

最佳答案

给定一个随机圆心(白色点)、一个随机边缘点(绿色)和第二个镜像边缘点(蓝色),您可以按如下方式计算 svg 弧。

  • 将水平和垂直椭圆半径设置为绿点和白点之间的距离
  • 将 x 轴旋转设置为零(因为旋转一个圆不会产生视觉差异)
  • 如果绿点位于白点上方,则将大弧标志设置为 1,否则设置为零(我认为这是您要问的关键问题)
  • 将扫描标志设置为零,因为黄色路径是从左图像边界到右图像边界任意绘制的,需要逆时针旋转圆弧路径轨迹
  • 将最终点设置为蓝点坐标

根据随机中心点和边缘点,针对不同的弧配置重复运行下面的代码片段。

var xmlns = "http://www.w3.org/2000/svg"; // svg namespace
var doc = document; // common abbreviation
var spc = " "; // space
var com = ","; // comma

var wd = 200; // svg width
var ht = 200; // svg height
var svg = doc.querySelector("svg"); // retrieve svg root element
setAttributes(svg, {width: wd, height: ht}); // set the svg dimensions
var cenX = wd / 2; // centre the circle horizontally
var cenY = Math.random() * (ht / 2) + (ht / 4); // pick a random circle centre height

var x1 = Math.random() * (wd / 3) + (wd / 7); // pick a random green point position
var y1 = Math.random() * (ht / 2) + (ht / 4);

var x2 = wd - x1; // mirror the blue point on the green point
var y2 = y1;

showPt(cenX, cenY, "white"); // show the white circle centre
showPt(x1, y1, "green"); // show the coloured edge points
showPt(x2, y2, "blue");

var path = doc.createElementNS(xmlns, "path"); // create the yellow path element
setAttributes(path, { // give it colour and width but no fill
  stroke: "yellow",
  "stroke-width": 3,
  fill: "none"
});
svg.appendChild(path); // add it to the picture

var rad = Math.sqrt((x1-cenX)*(x1-cenX) + (y1-cenY)*(y1-cenY)); // calculate the circle radius
var lgArcFlag = (y1 < cenY ? 1 : 0); // the arc will be large if the edge points are above the circle centre
setAttributes(path, { // create the trajectory of the yellow path
  d:
    "M" +
    "0," + y1 + // start it at the left border at the height of the green edge point
    "L" +
    x1 + com + y1 + spc + // draw it to the green edge point
    "A" + // make an arc
    rad + spc + rad + spc + // using the circle radius
    0 + spc + // with no rotation of the ellipse/circle
    lgArcFlag + spc + 0 + spc +  // using the large-arc-flag
    x2 + com + y2 + spc + // drawn to the blue edge point
    "L" +
    wd + com + y1 // and drawn straight out to the right border
});

function showPt(x, y, fill) {
  var pt = doc.createElementNS(xmlns, "circle");
  setAttributes(pt, {
    cx: x,
    cy: y,
    r: 8,
    fill: fill
  });
  svg.appendChild(pt);
  return pt;
}

function setAttributes(el, attrs) {
  var recursiveSet = function(at, set) {
    for (var prop in at) {
      var a = at[prop];
      if (typeof a === 'object' && a.dataset === undefined && a[0] === undefined) {
        recursiveSet(a, set [prop]);
      } else {
        set.setAttribute(prop, a);
      }
    }
  }
  recursiveSet(attrs, el);
}
<svg>
  <rect id="bkgd" fill="black" x="0" y="0" width="300" height="300" />
</svg>

关于svg - 在 SVG 上绘制圆的一段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35752231/

相关文章:

d3.js - 从函数附加时文本元素不可见

javascript - 更改 Highcharts 中的鼠标悬停点

objective-c - 如何在 xcode 项目中启用/禁用 ARC?

algorithm - 如何最快地检查点(3D)是否在点集给出的凸包内

selenium - 无法在 Selenium 上获取 moveToElement 显示 SVG 元素的工具提示

objective-c - 如何安全地将对象放入 __unsafe_unretained 数组中?

objective-c - 是否使用 loadNibNamed :owner:topLevelObjects: allows for weak references in top-level outlets?

python - 如何计算每个帖子的 xyz 位置和时间差的多边定位?

algorithm - 根据椭圆与长轴或短轴的角度求出椭圆的半径

javascript - 在全局/根坐标中确定 SVG 视口(viewport)