2016-11-29 85 views
0

如何查找SVG C(贝塞尔曲线)路径段的最左侧/最右侧?我知道有getBoundingClientRect()getBBox()但它们都不适用,因为它们只返回该点的单个坐标。查找SVG路径的最右侧/最左侧的点


,只是为了避免XY的问题 - 我想贝塞尔曲线组成的单一路径分成几个路径中的每个单调打算由左到右(或从右到左)。这意味着在任何单一路径上都不应该有2个具有相同X坐标的点。据我所知,所需的分割点可能会在之内一个段的边界框,因此不是最左边/最右边,但我几乎可以肯定,找到这样的点的方法应该使用相同的技术来找到水平的极端点。

+1

什么做的完整代码你的意思是'getBBpox(0'返回一个“单点”?'getBBox()'返回路径的边界框,最左边的点应该是'bbox.x',最右边的点应该是'bbox.x + bbox.width '那是你想要的吗? –

+0

'getBBox'可以让我知道目标点的x坐标,而不是'y'。这就是我说的只说单一坐标时的意思。 –

回答

0

保罗·勒博的评论和想象动画the wiki激发了我的解决方案。它主要基于以下方面:从[0, 1]参数t

  • 值可以匹配曲线 点。

  • 对于曲线上的任何参数值点可以通过对相邻控制点 的线性组合到较高的“深度”的中间控制点来构造 一步步骤。该操作 可以重复,直到曲线 本身只有单点左点。中间点的

  • 坐标可以通过同等程度的 t -polynoms被定义为指向“深度”。这些多项式的系数最终仅取决于初始控制点的坐标。

  • 倒数第二步的结构给出了2个点,定义切线 到最终点的曲线,这些点的坐标是由二次多项式控制的 。

  • 具有问题切线方向矢量允许 构造二次方程针对t其中曲线已要求 正切。

所以,其实,找到所需的积分可以在不断O(1)时间进行:

tangentPoints: function(tx, ty){ 
    var ends = this.getPolynoms(2); 
    var tangent = [ends[1][0].subtractPoly(ends[0][0]), 
        ends[1][1].subtractPoly(ends[0][1])]; 
    var eq = tangent[0].multiplyScalar(ty).subtractPoly(tangent[1].multiplyScalar(tx)); 
    return solveQuadratic(...eq.values).filter(t => t >= 0 && t <= 1); 
    } 

与协助Polynom类和视觉演示中,我放入this repofiddle

0

您需要用.getPointAtLength(i)方法遍历路径长度,然后找到限制。似乎是一个有趣的事情,所以我做了一个快速和肮脏的实施,这是重要的部分:

function findLimits(path) { 

    var boundingPoints = { 
    minX: {x: dimensions.width, y: dimensions.height}, 
    minY: {x: dimensions.width, y: dimensions.height}, 
    maxX: {x: 0, y: 0}, 
    maxY: {x: 0, y: 0} 
    } 
    var l = path.getTotalLength(); 
    for (var p = 0; p < l; p++) { 
    var coords = path.getPointAtLength(p); 
    if (coords.x < boundingPoints.minX.x) boundingPoints.minX = coords; 
    if (coords.y < boundingPoints.minY.y) boundingPoints.minY = coords; 
    if (coords.x > boundingPoints.maxX.x) boundingPoints.maxX = coords; 
    if (coords.y > boundingPoints.maxY.y) boundingPoints.maxY = coords; 
    } 
    return boundingPoints 
} 

您可以在这里找到实现:https://jsfiddle.net/4gus3hks/1/

enter image description here

+0

这具有线性O(长度)性能。有没有办法更快地做到这一点,或者有些常规的开箱即用的方法? –

+1

看到这个问题的数学解决方案,而不是一个迭代。 http://stackoverflow.com/questions/24809978/calculating-the-bounding-box-of-cubic-bezier-curve –