将贝塞尔曲线分成两半相等 [英] Divide bezier curve into two equal halves

查看:120
本文介绍了将贝塞尔曲线分成两半相等的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有2点之间的bezier曲线。我想将所有曲线切成两个相等的一半。
我的一个想法是,如果我可以控制't'值,我将通过t = [0,0.5]和t = [0.5,1]绘制2条曲线,但我不知道如何。以下是我的代码。我不介意任何其他想法或建议

I have the bezier curves between 2 points. I'd like to cut all curves into two equal half. One of my idea is if I can control 't' value I'll draw 2 curves by t = [0,0.5] and t = [0.5,1] but I don't know how. Below is my code. I won't mind any other idea or suggestion

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>D3 test</title>
    <script src="http://d3js.org/d3.v3.min.js"></script>

    <script>
    var Over = function(){
        d3.select(this)
        .style("stroke-opacity", 0.25);
    }
    var Out = function(){
        d3.select(this)
        .transition().duration(200)
        .style("stroke-opacity", 0);
    }

    function curve(n,x1,y1,x2,y2){

        var xr = (x1+x2)/2,
            yr = (y1+y2)/2,
            euDist = Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2)),
            x3 = -y1+xr+yr, x4 = -y2+xr+yr,
            y3 =  x1+yr-xr, y4 =  x2+yr-xr,
            ctrl , curveDescription;

        svg.append('path')
            .attr("stroke", 'blue')
            .attr('fill','none')
            .style("stroke-opacity",0.25)
            .attr('d', 'M'+x3+','+y3+'L'+x4+','+y4)
            .attr('stroke-width',strokeWidth);

        for(var j=0;j<=n;j++){
            ctrl = [(x4-x3)*j/n+x3 , (y4-y3)*j/n+y3] ,                  
            curveDescription=   
                    'M' +x1+','     +y1+ 
                    'Q' +ctrl[0]+','+ctrl[1]+','
                        +x2+','     +y2;

            svg.append('path')
                .attr("stroke", 'blue')
                .attr('fill','none')
                .style("stroke-opacity",0.25)
                .attr('d', curveDescription)
                .attr('stroke-width',strokeWidth);  

            svg.append('path')
                .attr("stroke", 'blue')
                .attr('fill','none')
                .style("stroke-opacity",0)
                .on("mouseover", Over)
                .on("mouseout", Out)
                .attr('d', curveDescription)
                .attr('stroke-width',strokeWidth*25);

        }

    }
    </script>

</head>

<body>
    <script>
    var w = 1268 , h = 680 , strokeWidth = 2;

    var svg = d3.select("body")
                .append("svg")
                .attr("width", w)
                .attr("height", h)

    curve(5, 100,100, 400,500);


    </script>
</body>
</html>


推荐答案

将贝塞尔曲线分成两条曲线非常简单。查看De Casteljau的算法。 https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm

Splitting a bezier into two curves is fairly simple. Look up De Casteljau's Algorithm. https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm

更新

De Casteljau比看起来更简单。对于非mathermeticians而言,WP文章可能更清楚。所以我会更简单地解释一下。

De Casteljau is simpler than it looks. That WP article could be clearer for non-mathermeticians. So I'll explain more simply.

想象一下你有一个由A,B,C和A点定义的bezier。 D.其中A和D是终点,B和C是控制点。

Imagine you have a bezier defined by the points A,B,C & D. Where A and D are the endpoints and B and C are the control points.

所以,你想要在't'点找到曲线的值沿着曲线(其中t在0..1范围内。你可以通过几何形状这样做:

So, say you wanted to find the value of the curve at point 't' along the curve (where t is in the range 0..1. You can do it this way by geometry:


  1. 找到E点沿着直线AB在't'处。

  2. 沿直线BC找到't'处的点F.

  3. 找到沿着直线CD在't'处的点G.

  1. Find the point E that is at 't' along the straight line AB.
  2. Find the point F that is at 't' along the straight line BC.
  3. Find the point G that is at 't' along the straight line CD.

找到直线上't'处的点H.线EF。

Find the point H that is at 't' along the straight line EF.

找到沿直线FG位于't'的点J.

Find the point J that is at 't' along the straight line FG.

最后,沿着直线HJ找到位于't'的点K.

Finally, find the point K that is at 't' along the straight line HJ.

K也等于bezier上的't'点。这是De Casteljau的算法。

K is also equal to the point that is 't' along the bezier. This is De Casteljau's Algorithm.

但是有用的是,它也给了我们两个的控制点如果是,那将导致的beziers e曲线在点K处分开。两条贝塞尔曲线为:A,E,H,K和K,J,G,D。

But usefully, it also gives us the control points of the two beziers that would result if the curve was split at point K. The two bezier curves are: A,E,H,K and K,J,G,D.

在您的情况下t = 0.5,所以找到两条曲线只是一系列加法和除以2。

In your case t=0.5, so finding the two curves is just a sequence of additions and divides-by-2.

  E = (A+B)/2
  F = (B+C)/2
  G = (C+D)/2
  H = (E+F)/2
  J = (F+G)/2
  K = (H+J)/2

显然每个这些计算必须针对x和y进行。

Obviously each of these calculations has to be done for x and y.

希望这会有所帮助。

这篇关于将贝塞尔曲线分成两半相等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆