【问题标题】:Calculate a curve that goes through all the points计算通过所有点的曲线
【发布时间】:2020-11-20 17:08:56
【问题描述】:

我无法像 SVG 中的贝塞尔曲线那样构建一条穿过所有点但不在这些点之外的曲线。

我试过了 贝塞尔曲线, 二次曲线, 平滑曲线, 和Casteljau

这是我的示例的链接https://dotnetfiddle.net/KEqts0

很遗憾,我可以使用第 3 方进行映射。

我不想把输出放在里面,因为那只是噪音,我已经附上了一张图片供参考。

【问题讨论】:

  • “一条穿过所有点的曲线”:这是未指定的。分段线性曲线适合您吗?

标签: c# svg bezier cubic-bezier


【解决方案1】:

观察:最初的问题被标记为javascript。发布我的答案后,javascript 标记被删除(不是由 OP)。

给定一个点数组pointsRy,您需要计算贝塞尔曲线控制点的位置。第一条和最后一条曲线是二次贝塞尔曲线。所有其他曲线都是三次贝塞尔曲线。

这是一张我标记点和通过每个点的曲线的切线的图像。控制点是切线的起点和终点。

切线的大小是相对于点之间的距离计算的:let t = 1 / 5; 更改此项以更改曲率。

let svg = document.querySelector("svg")

let t = 1 / 5;// change this to change the curvature

let pointsRy = [[100,100],[250,150],[300,300],[450,250], [510,140],[590,250],[670,140]];

thePath.setAttribute("d", drawCurve(pointsRy));

function drawCurve(p) {

  var pc = controlPoints(pointsRy); // the control points array

  let d="";
  d += `M${p[0][0]}, ${p[0][1]}`
  
  // the first & the last curve are quadratic Bezier
  // because I'm using push(), pc[i][1] comes before pc[i][0]
  d += `Q${pc[1][1].x}, ${pc[1][1].y}, ${p[1][0]}, ${p[1][1]}`;


  if (p.length > 2) {
    // central curves are cubic Bezier
    for (var i = 1; i < p.length - 2; i++) {
      
     d+= `C${pc[i][0].x}, ${pc[i][0].y} ${pc[i + 1][1].x},${pc[i + 1][1].y} ${p[i + 1][0]},${p[i + 1][1]}`; 

    }//end for
    // the first & the last curve are quadratic Bezier
    let n = p.length - 1;
    d+=`Q${pc[n - 1][0].x}, ${pc[n - 1][0].y} ${p[n][0]},${p[n][1]}`;
  }
  return d;
}
function controlPoints(p) {
  // given the points array p calculate the control points
  let pc = [];
  for (var i = 1; i < p.length - 1; i++) {
    let dx = p[i - 1][0] - p[i + 1][0]; // difference x
    let dy = p[i - 1][1] - p[i + 1][1]; // difference y
    // the first control point
    let x1 = p[i][0] - dx * t;
    let y1 = p[i][1] - dy * t;
    let o1 = {
      x: x1,
      y: y1
    };

    // the second control point
    var x2 = p[i][0] + dx * t;
    var y2 = p[i][1] + dy * t;
    var o2 = {
      x: x2,
      y: y2
    };

    // building the control points array
    pc[i] = [];
    pc[i].push(o1);
    pc[i].push(o2);
  }
  return pc;
}
body{background:black; margin:1em;}
svg{border: 1px solid #999;}
path{fill:none; stroke:white;}
<svg viewBox="0 0 800 400">  
  <path id="thePath" stroke="white"/>
</svg>

【讨论】:

  • 你应该为此获得 1,000,000 票。您不知道找到执行此功能的可靠代码是多么困难(使贝塞尔曲线 + 三次曲线路径通过 0..N 个点的数组)。非常感谢你做的这些!效果很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-19
  • 1970-01-01
  • 1970-01-01
  • 2011-08-03
  • 2013-02-07
  • 1970-01-01
相关资源
最近更新 更多