在两点之间创建svg弧

Ion*_*zău 23 javascript svg svg.js

我想使用弧连接两个SVG点(例如两个圆的中心).如果只有一个连接,则line(<path>)将是直的.如果有两个连接,则两个连接都将是圆形的并且是对称的,这样:

所以,实际上,规则很少:

  1. 一切都应该与连接两点的假想线对称.
  2. 从1开始,很明显,如果连接数是:

    • 奇数:我们不显示直线
    • 偶数:我们显示直线
  3. 应该有一个值k来定义相同点之间的两个连接之间的距离.

  4. 穿过椭圆弧中间的切线应与连接两个点的直线平行.显然,线的中间将垂直于切线.

我很难得到一个公式来计算元素中的A参数<path>.

我到现在所做的是:

<path d="M100 100, A50,20 0 1,0 300,100" stroke="black" fill="transparent"/>
Run Code Online (Sandbox Code Playgroud)
  • M100 100很明确:这是起点(移至100,100)
  • 最后两个数字也很清楚.路径结束300,100
  • 我也看到,如果我把它0代替20,我得到一条直线.
  • 如果我替换1,01,1,则路径被翻转.

我不知道的是如何计算A参数.我阅读了文档,但想象仍然不清楚.如何计算这些值?

svg {
  width: 100%;
  height: 100%;
  position: absolute;
}
Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>

<body>
  <?xml version="1.0" standalone="no" ?>

    <svg version="1.1" xmlns="http://www.w3.org/2000/svg">
      <!-- Connect A(100,100) with B(300, 100) -->
      <path d="M100 100, A50,0 0 1,0 300,100" stroke="black" fill="transparent" />
      <path d="M100 100, A50,20 0 1,0 300,100" stroke="black" fill="transparent" />
      <path d="M100 100, A50,20 0 1,1 300,100" stroke="black" fill="transparent" />
      <path d="M100 100, A50,30 0 1,0 300,100" stroke="black" fill="transparent" />
      <path d="M100 100, A50,30 0 1,1 300,100" stroke="black" fill="transparent" />
      
      <!-- A(100, 100) B(300, 400) -->
      <path d="M100 100, A50,0 57 1,0 300,400" stroke="black" fill="transparent" />
      <path d="M100 100, A50,20 57 1,0 300,400" stroke="black" fill="transparent" />
      <path d="M100 100, A50,20 57 1,1 300,400" stroke="black" fill="transparent" />
  </svg>
</body>

</html>
Run Code Online (Sandbox Code Playgroud)

我正在使用SVG.js来创建路径.

squ*_*age 17

你需要圆弧,让自己的生活变得非常困难.

如果改为使用二次曲线,则几何变得非常简单 - 只需将中心X坐标偏移Y坐标差异的一半,反之亦然.

function arc_links(dwg,x1,y1,x2,y2,n,k) {
  var cx = (x1+x2)/2;
  var cy = (y1+y2)/2;
  var dx = (x2-x1)/2;
  var dy = (y2-y1)/2;
  var i;
  for (i=0; i<n; i++) {
    if (i==(n-1)/2) {
      dwg.line(x1,y1,x2,y2).stroke({width:1}).fill('none');
    }
    else {
      dd = Math.sqrt(dx*dx+dy*dy);
      ex = cx + dy/dd * k * (i-(n-1)/2);
      ey = cy - dx/dd * k * (i-(n-1)/2);
      dwg.path("M"+x1+" "+y1+"Q"+ex+" "+ey+" "+x2+" "+y2).stroke({width:1}).fill('none');
    }
  }
}

function create_svg() {
  var draw = SVG('drawing').size(300, 300);
  arc_links(draw,50,50,250,50,2,40);
  arc_links(draw,250,50,250,250,3,40);
  arc_links(draw,250,250,50,250,4,40);
  arc_links(draw,50,250,50,50,5,40);
  draw.circle(50).move(25,25).fill('#fff').stroke({width:1});
  draw.circle(50).move(225,25).fill('#fff').stroke({width:1});
  draw.circle(50).move(225,225).fill('#fff').stroke({width:1});
  draw.circle(50).move(25,225).fill('#fff').stroke({width:1});
}

create_svg();
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/2.3.2/svg.min.js"></script>
<div id="drawing"></div>
Run Code Online (Sandbox Code Playgroud)


Str*_*e Q 7

为了绘制SVG路径的圆弧,你需要2个点和半径,有2个点,你只需要计算给定距离的半径。

半径公式:

let r = (d, x) => 0.125*d*d/x + x/2;

在哪里:

d- 点之间的距离

x- 弧之间的距离

它源自毕达哥拉斯定理

在此输入图像描述

a这是点之间距离的一半


let r = (d, x) => !x?1e10:0.125*d*d/x + x/2; 

upd();

function upd() {
  let n = +count.value;
  let s = +step.value/10;
  let x1 = c1.getAttribute('cx'), y1 = c1.getAttribute('cy');
  let x2 = c2.getAttribute('cx'), y2 = c2.getAttribute('cy');
  let dx = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
  paths.innerHTML = [...Array(n)].map((_, i) => [
    n%2&&i===n-1?0:1+parseInt(i/2),
    i%2
  ]).map(i => `<path d="${[
    'M', x1, y1,
    'A', r(dx, s*i[0]), r(dx, s*i[0]), 0, 0, i[1], x2, y2
  ].join(' ')}"></path>`).join('');
}
Run Code Online (Sandbox Code Playgroud)
<input id="count" type="range" min=1 max=9 value=5 oninput=upd() >
<input id="step" type="range" min=1 max=200 value=100 oninput=upd() >
<svg viewbox=0,0,300,100 stroke=red fill=none >
  <circle id=c1 r=10 cx=50 cy=60></circle>
  <circle id=c2 r=10 cx=250 cy=40></circle>
  <g id=paths></g>
</svg>
Run Code Online (Sandbox Code Playgroud)