svg - 使用贝塞尔曲线或椭圆路径以编程方式绘制椭圆的一部分 — SVG 和 raphael.js

标签 svg raphael bezier ellipse elliptic-curve

我正在尝试绘制一条围绕给定边距的椭圆的贝塞尔曲线:

Bezier path surrounding an ellipse

我想以编程方式实现此目的,因此如果我更改椭圆大小,曲线将跟随它。

目前我已经实现了这个功能:

function bezierPathTopRounded(ellipse, margin) {
    var box = ellipse.paper.getBBox();

    var leftX = box.x - margin; 

    var rightX = box.x + margin + box.width;

    var y = box.y + box.height/2 - margin; 

    var p = "M "+ leftX  + ", "+ y
    + " C " //could be relative too
    + ( box.x - margin + (box.width/15)  )  + ", " + ( box.y + margin - (box.height/4.5)  ) + " "
    + ( box.x + margin + box.width - (box.width/15)  )  + ", " + ( box.y + margin - (box.height/4.5) ) + " "
    + rightX +", " + y;

    return p;   
}

但我不知道如何计算这个方向点值,以便它适用于任何椭圆:

  • box.width/15
  • 盒子高度/4.5

有一个fiddle with this example .

我读过这篇文章stackoverflow question我在我的例子中尝试了同样的方法,但仍然无法找出一个简单的解决方案,它仍然是随机的......

编辑

现在我尝试使用椭圆Arc,结果比贝塞尔路径更糟糕:

Elliptical Arc test

这是我正在使用的功能。如果我删除边距,它会完全跟随我的椭圆...最后,问题是我如何才能跟随带有边距的椭圆?

function borderPath(ellipse, margin, flag) {
    var flag = flag == undefined ? 1 : 0;

    var box = ellipse.paper.getBBox();

    var leftX = box.x - margin;

    var rightX = box.x + margin + box.width;

    var y = box.y + box.height/2;
    y += (flag == 1) ? -margin : margin;

    var rx = box.width/2 + margin;
    var ry = box.height/2;

    var p = "M "+ leftX + ", "+ y
    + " A "
    + rx + " " + ry
    + " 0 0 "+ flag +" "
    + rightX +", " + y;

    return p;
}

请参阅updated fiddle here .

对于糟糕的颜色真的很抱歉,这些只是为了举例。

最佳答案

如果你想用贝塞尔曲线来做到这一点,你必须决定你希望它看起来有多“错误”。贝塞尔曲线不能表示圆形(并且通过扩展,椭圆形)曲线,它们只能非常接近,就像多边形一样,只是使用更少的部分获得更高的精度。

我在《贝塞尔曲线入门》http://pomax.github.io/bezierinfo/#circles_cubic 中使用贝塞尔曲线描述了圆近似和曲线偏移。和 http://pomax.github.io/bezierinfo/#offsetting分别,但如果您从头开始编码,特别是如果您只需要它来实现示例中描述的内容,那么偏移将是过度的。

相反,我建议启动 Inkscape 或 Illustrator,打开网格叠加层,然后在椭圆周围绘制贝塞尔曲线。让它看起来不错,然后检查坐标是什么,并将其用作在 Canvas 程序中实现的足够可靠的信息。你可能不需要在数学上严格正确,只要人们不去“看起来不对”,你应该没问题。

关于svg - 使用贝塞尔曲线或椭圆路径以编程方式绘制椭圆的一部分 — SVG 和 raphael.js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16100048/

相关文章:

javascript - 向 Raphael.js 文本元素添加附加数据

javascript - 如何在 HTML Canvas 上绘制可变粗细的贝塞尔曲线?

iphone - 更改贝塞尔曲线的颜色

algorithm - 逐像素贝塞尔曲线

svg - 是否可以在 svg 矩形中设置负宽度?

javascript - Raphaël - transformPath() 返回直线而不是曲线

html - URL 不适用于 SVG 图形

javascript - SVG Raphael jQuery 构建路径/轨迹

html - Flexbox Div 不包含 Safari 中的所有元素,但在 Chrome 中工作正常

javascript - mapbox studio 中可见的图标未通过 mapbox gl 显示