具有三个手柄的贝塞尔曲线错位了控制点 [英] Bezier curve with three handles misplaces the control points

查看:106
本文介绍了具有三个手柄的贝塞尔曲线错位了控制点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我设法用Raphael库的例子绘制了四条不同的曲线。现在,我想创建一个包含多个手柄的曲线。如何在此示例中添加更多句柄。

I managed to draw four different curves with the examples of the Raphael library. Now, I would like to create a single curve with multiple handles in it. How do I add more handles in this example.

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Bezier curve</title>
            <style>
        #holder {
            height: 100%;
            left: 100%;
            margin: -100% 0 0 -100%;
            position: absolute;
            top: 100%;
            width: 100%;
        }
        </style>
        <script src='jquery.js'></script>
        <script src="raphael.js"></script>
        <script>
           $('document').ready(function () {
                var r = Raphael("holder", window.innerWidth, window.innerHeight)

                function curve(x, y, ax, ay, bx, by, zx, zy, color) {
                    var path = [["M", x, y], ["C", ax, ay, bx, by, zx, zy]],
                        path2 = [["M", x, y], ["L", ax, ay], ["M", bx, by], ["L", zx, zy]],
                        curve = r.path(path).attr({stroke: color || Raphael.getColor(), "stroke-width": 4, "stroke-linecap": "round"}),
                        controls = r.set(
                            r.path(path2).attr({stroke: "#ccc", "stroke-dasharray": ". ","stroke-width":2}),
                            r.circle(x, y, 5).attr({fill: "#9F2200", stroke: "none"}),
                            r.circle(ax, ay, 5).attr({fill: "#9F2200", stroke: "none"}),
                            r.circle(bx, by, 5).attr({fill: "#9F2200", stroke: "none"}),
                            r.circle(zx, zy, 5).attr({fill: "#9F2200", stroke: "none"})
                        );
                    controls[1].update = function (x, y) {
                        var X = this.attr("cx") + x,
                            Y = this.attr("cy") + y;
                        this.attr({cx: X, cy: Y});
                        path[0][1] = X;
                        path[0][2] = Y;
                        path2[0][2] = X;
                        path2[0][2] = Y;
                        controls[2].update(x, y);
                    };
                    controls[2].update = function (x, y) {
                        var X = this.attr("cx") + x,
                            Y = this.attr("cy") + y;
                        this.attr({cx: X, cy: Y});
                        path[1][3] = X;
                        path[1][2] = Y;
                        path2[1][4] = X;
                        path2[1][2] = Y;
                        curve.attr({path: path});
                        controls[0].attr({path: path2});
                    };
                    controls[3].update = function (x, y) {
                        var X = this.attr("cx") + x,
                            Y = this.attr("cy") + y;
                        this.attr({cx: X, cy: Y});
                        path[1][3] = X;
                        path[1][4] = Y;
                        path2[2][5] = X;
                        path2[2][2] = Y;
                        curve.attr({path: path});
                        controls[0].attr({path: path2});
                    };
                    controls[4].update = function (x, y) {
                        var X = this.attr("cx") + x,
                            Y = this.attr("cy") + y;
                        this.attr({cx: X, cy: Y});
                        path[1][5] = X;
                        path[1][6] = Y;
                        path2[3][6] = X;
                        path2[3][2] = Y;
                        controls[3].update(x, y);
                    };
                    controls.drag(move, up);
                }
                function move(dx, dy) {
                    this.update(dx - (this.dx || 0), dy - (this.dy || 0));
                    console.log(this.dx,this.dy);
                    this.dx = dx;
                    this.dy = dy;
                }
                function up() {
                    this.dx = this.dy = 0;
                }
                curve(70, 100, 110, 100, 130, 200, 170, 200, "hsb(0, 0, 0)");
                 curve(800, 200, 800, 100, 600, 100, 600, 200, "hsb(0, 0, 0)");  // xp1,yp1,  , , , , xp2,yp2 where (xp1,xp2) & (xp2,yp2) are two end points 

                  curve(500, 200,500, 300, 300, 300, 300, 200, "hsb(0, 0, 0)");  // xp1,yp1,  , , , , xp2,yp2 where (xp1,xp2) & (xp2,yp2) are two end points 

                    curve(920, 100,880, 100, 1020, 200, 980, 200, "hsb(0, 0, 0)"); 

            });
        </script>
    </head>
    <body>
        <div id="holder"></div>
    </body>
</html>

</body>

演示的链接是< a href =http://jsfiddle.net/insane36/fddGJ/1/ =nofollow noreferrer> http://jsfiddle.net/insane36/fddGJ/1/

我编辑了代码并再次尝试放置多个句柄以显示中间的主句柄但有一些问题,我不知道我是否理解它背后的概念。我想创建一个带有句柄的图形如下图所示,并且能够操纵句柄;

I edited the code and again tried to put multiple handle to show the main handle in the middle but has some problem and I dont know if I understood the concept behind it. I wanted to create a figure with handle as figure below and be able to manipulate the handles;

三个句柄的代码是;

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Bezier curve</title>
            <style>
        #holder {
            height: 100%;
            left: 100%;
            margin: -100% 0 0 -100%;
            position: absolute;
            top: 100%;
            width: 100%;
        }
        </style>
        <script src="raphael.js"></script>
        <script>
           window.onload=function () {
                var r = Raphael("holder", window.innerWidth, window.innerHeight)

                function curve(x1, y1, cx1, cy1, cx2, cy2, x2, y2,cx3,cy3,cx4,cy4, color) {  //zx --x1
                    var path = [["M", x1, y1], ["C", cx1, cy1, cx2, cy2, x2, y2,"S",cx3,cy3,cx4,cy4]],
                        path2 = [["M", x1, y1], ["L", cx1, cy1], ["M", cx2, cy2], ["L", x2, y2],["M", cx3,cy3],['L',cx4,cy4]],
                        curve = r.path(path).attr({stroke: color || Raphael.getColor(), "stroke-width": 4, "stroke-linecap": "round"}),
                        controls = r.set(
                            r.path(path2).attr({stroke: "#ccc", "stroke-dasharray": ". ","stroke-width":2}),
                            r.circle(x1, y1, 5).attr({fill: "#9F2200", stroke: "none"}),
                            r.circle(cx1, cy1, 5).attr({fill: "#9F2200", stroke: "none"}),
                            r.circle(cx2, cy2, 5).attr({fill: "#9F2200", stroke: "none"}),
                            r.circle(x2, y2, 5).attr({fill: "#9F2200", stroke: "none"}),
                             r.circle(cx3, cy3, 5).attr({fill: "#9F2200", stroke: "none"}),
                              r.circle(cx4, cy4, 5).attr({fill: "#9F2200", stroke: "none"})

                        );
                    controls[1].update = function (x, y) {
                        var X = this.attr("cx") + x,
                            Y = this.attr("cy") + y;
                        this.attr({cx: X, cy: Y});
                        path[0][9] = X;
                        path[0][2] = Y;
                        path2[0][10] = X;
                        path2[0][2] = Y;
                        controls[2].update(x, y);
                    };
                    controls[2].update = function (x, y) {
                        var X = this.attr("cx") + x,
                            Y = this.attr("cy") + y;
                        this.attr({cx: X, cy: Y});
                        path[1][11] = X;
                        path[1][2] = Y;
                        path2[1][12] = X;
                        path2[1][2] = Y;
                        curve.attr({path: path});
                        controls[0].attr({path: path2});
                    };
                    controls[3].update = function (x, y) {
                        var X = this.attr("cx") + x,
                            Y = this.attr("cy") + y;
                        this.attr({cx: X, cy: Y});
                        path[1][3] = X;
                        path[1][4] = Y;
                        path2[2][13] = X;
                        path2[2][2] = Y;
                        curve.attr({path: path});
                        controls[0].attr({path: path2});
                    };
                    controls[4].update = function (x, y) {
                        var X = this.attr("cx") + x,
                            Y = this.attr("cy") + y;
                        this.attr({cx: X, cy: Y});
                        path[1][5] = X;
                        path[1][6] = Y;
                        path2[3][14] = X;
                        path2[3][2] = Y;
                        controls[3].update(x, y);
                    };
                    controls[5].update = function (x, y) {
                        var X = this.attr("cx") + x,
                            Y = this.attr("cy") + y;
                        this.attr({cx: X, cy: Y});
                        path[1][8] = X;
                        path[1][9] = Y;
                        path2[4][15] = X;
                        path2[4][2] = Y;
                        controls[4].update(x, y);
                    };
                      controls[6].update = function (x, y) {
                        var X = this.attr("cx") + x,
                            Y = this.attr("cy") + y;
                        this.attr({cx: X, cy: Y});
                        path[1][10] = X;
                        path[1][11] = Y;
                        path2[5][16] = X;
                        path2[5][2] = Y;
                        controls[5].update(x, y);
                    };

                    controls.drag(move, up);
                }
                function move(dx, dy) {
                    this.update(dx - (this.dx || 0), dy - (this.dy || 0));
                    console.log(this.dx,this.dy);
                    this.dx = dx;
                    this.dy = dy;
                }
                function up() {
                    this.dx = this.dy = 0;
                }
                curve(10, 80, 40, 10, 65,10,150,150,95, 80,  180,180, "hsb(0, 0, 0)");

            };
        </script>
    </head>
    <body>
        <div id="holder"></div>
    </body>
</html>

</body>
</html>

我想我错过了并没有正确安排控制点和价值

I think I have missed and not arranged properly the control points and the values

推荐答案

看看这个小提琴 - 我想我正在做你正在寻找的事情。 (编辑:修复了这个小提琴,因此您不必在 curve()构造函数中指定反射控制点)

Take a look at this fiddle - I think I have it doing what you are looking for. ( fixed this fiddle so you don't have to specify the reflected control point in the curve() constructor)

我认为关键是曲线中间点的第二个控制点只是第一个控制点的反映(根据 SVG文档),所以你必须对那些控件进行伪造。 (您的代码确实存在一些问题,其中您的update()函数正在尝试更新不存在的数组值,例如 path [1] [6] = Y; ... 路径[1] 只有三个元素)

I think the key is that the second control point of the middle point on the curve is just a reflection of the first control point (per the SVG documentation), so you have to sort of 'fake' that control. (Your code did have some issues where your update() functions were trying to update array values that don't exist, like path[1][6] = Y; ... path[1] only has three elements)

如果你想要两个控制点独立运行(这样曲线在这一点上不一定是平滑的),我认为你必须从你的路径中删除S,并改变一些代码(这里是类似的一个

If you want the two control points to behave independently (so that the curve would not necessarily be smooth through that point), I think you have to remove the "S" from your path, and change some of the code (here is one like that)

如果你想要两个控制点是允许从点移动不同的距离,但保持曲线平滑点,我认为你必须手动完成。您可以从第二个示例开始,但是您必须以编程方式将移动控制点的角度反映到相对的控制点,同时允许从相对控制点到曲线上的点的距离保持固定。

If you want the two control points to be allowed to move different distances from the point, but keep the curve smooth through the point, I think you have to do that by hand. You could start with the second example, but you would have to programatically reflect the angle of the moving control point to the opposite control point, while allowing the distance from the opposite control point to the point on the curve to remain fixed.

这篇关于具有三个手柄的贝塞尔曲线错位了控制点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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