java - 如何使用贝塞尔曲线操纵端点角度

标签 java swing geometry bezier

我想在两个形状(就本问题而言为矩形)之间生成一条贝塞尔曲线,使得曲线与形状成 90 度角。下面是 MS Paint 生成的示例:

example curve

就我的目的而言,可以假设角度只需要垂直于轴,而不是任意的东西。也就是说,曲线端点处的角度只需为0、90、180或270度即可。

我对贝塞尔曲线的理解告诉我,我需要 2 个端点和 2 个控制点。端点计算起来很简单,但我对如何操纵控制点只有基本的了解。

有一个方便的公式来完成这个吗?我在寻找相关教程时遇到了令人惊讶的困难。

我正在使用 Java,目前正在使用 java.awt.geom.Path2D.Double.curveTo() 绘制曲线。如果有一个预先构建的 Java 类或方法来完成此任务,那将是理想的选择,但如果需要,我愿意自己实现一个算法或方程。

最佳答案

基于 Sage 的出色回答并在尝试了 http://www.openprocessing.org/sketch/2123 之后有一段时间,这就是我的最终结果。

将控制点与要创建的角度共线会沿该方向拉动曲线。控制点距端点越远,效果越明显。由于我只处理 90 度角,这意味着我只需将控制点的 x 或 y 坐标更改设定的距离(我将其称为 delta,就像 Sage 那样)即可产生所需的效果。我没有使用任何花哨的东西来查找增量 - 我只是尝试了几个值,直到找到一个我满意的值。

这是我的最终代码的片段。

public class BezierCurve {
    private CubicCurve2D curve;

    private static final int delta = 100;

    private double x1, y1, x2, y2;
    private double ctrlx1, ctrly1, ctrlx2, ctrly2;

    public BezierCurve(Point p1, Side side1, Point p2, Side side2) {
        this.x1 = p1.x;
        this.y1 = p1.y;
        this.x2 = p2.x;
        this.y2 = p2.y;

        Point ctrl1 = getControlPoint(p1, side1);
        Point ctrl2 = getControlPoint(p2, side2);

        ctrlx1 = ctrl1.x;
        ctrly1 = ctrl1.y;
        ctrlx2 = ctrl2.x;
        ctrly2 = ctrl2.y;

        curve = new CubicCurve2D.Double();
        curve.setCurve(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2);
    }

    private Point getControlPoint(Point p, Side s) {
        int x = p.x;
        int y = p.y;

        switch (s) {
        case Left:
            x -= delta;
            break;
        case Right:
            x += delta;
            break;
        case Bottom:
            y += delta;
            break;
        case Top:
            y -= delta;
            break;
        }
        return new Point(x, y);
    }

    public void draw(Graphics2D g2) {
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.draw(curve);
    }
}

这会处理顶部、底部、右侧和左侧的每种情况。

这是正在运行的代码的屏幕截图。

enter image description here

关于java - 如何使用贝塞尔曲线操纵端点角度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19817733/

相关文章:

java - 与 Jersey 客户端发送多部分请求

java - undertow 编译错误

java - Android Java - String .replaceAll 替换特定字符(正则表达式)

java - 尝试制作一款基于 Ascii 的游戏; JFrame不显示

java - Groovy - 如何创建内部包含变量的路径目录

java - JTextArea 在 actionListener 之前填充

java - 如何在构造函数外将 Jlabel 添加到 Jpanel?

android - OpenGL : Drawing Quad - Color fading issue

algorithm - 寻找二维点云的内圆/椭圆

python - 在opencv2中使用3D感知