【问题标题】:Draw segment of circle on SVG在SVG上绘制圆段
【发布时间】:2016-06-15 14:26:26
【问题描述】:

给定下一个信息:

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

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

使用带有 SVG 的弧(A 椭圆),我得到 2 个带有 large_arc_flag 的选项

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

我该如何解决?

谢谢!

【问题讨论】:

    标签: svg automatic-ref-counting geometry


    【解决方案1】:

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

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

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

    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>

    【讨论】:

      猜你喜欢
      • 2015-07-04
      • 2018-06-23
      • 2017-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-23
      • 1970-01-01
      相关资源
      最近更新 更多