Java 动画并重写绘制和更新方法

发布于 2024-12-13 02:40:39 字数 2817 浏览 0 评论 0原文

所以目前我正在尝试为不同顺序的贝塞尔曲线和组成它们的中点设置动画,但我对 Java 中的图形还很陌生。我了解绘画和重新绘画的工作原理,但我不知道如何摆脱这种情况。

贝塞尔曲线点由用户点击决定,并在 mouseEvent 中调用 repaint()。

public void paint(Graphics g) {
    initgr();
    int left = iX(-rWidth / 2), right = iX(rWidth / 2), bottom = iY(-rHeight / 2), top = iY(rHeight / 2);
    g.drawRect(left, top, right - left, bottom - top);

    for (int i = 0; i < np; i++) {
        // Show tiny rectangle around point:
        g.drawRect(iX(P[i].x) - 2, iY(P[i].y) - 2, 4, 4);
        if (i > 0)
            // Draw line P[i-1]P[i]:
            g.drawLine(iX(P[i - 1].x), iY(P[i - 1].y), iX(P[i].x),
                    iY(P[i].y));
    }

    if (np == 2 && order == 1)
        bezier1(g, P, gran);
    if (np == 3 && order == 2)
        bezier2(g, P, gran);
    if (np == 4 && order == 3)
        bezier3(g, P, gran);
    if (np == 5 && order == 4)
        bezier4(g, P, gran);
    if (np == 6 && order == 5)
        bezier5(g, P, gran);
}

底部调用的函数将转到此处计算和绘制的贝塞尔曲线。

void bezier3(Graphics g, Point2D[] p, int n) {
    javax.swing.Timer timer = new javax.swing.Timer(100,
            new TimerListener());
    timer.setDelay(39);
    timer.start();
    float dt = 1.0F / n, cx3 = -p[0].x + 3 * (p[1].x - p[2].x) + p[3].x, cy3 = -p[0].y
            + 3 * (p[1].y - p[2].y) + p[3].y, cx2 = 3 * (p[0].x - 2
            * p[1].x + p[2].x), cy2 = 3 * (p[0].y - 2 * p[1].y + p[2].y), cx1 = 3 * (p[1].x - p[0].x), cy1 = 3 * (p[1].y - p[0].y), cx0 = p[0].x, cy0 = p[0].y, x = p[0].x, y = p[0].y, x0, y0, x2, y2;
    for (int i = 1; i <= n; i++) {

        float t = i * dt;

        x0 = x;
        y0 = y;
        x = ((cx3 * t + cx2) * t + cx1) * t + cx0;
        y = ((cy3 * t + cy2) * t + cy1) * t + cy0;
        // x2 = ((cx3 * (.5F*t) + cx2) * (.5F*t) + cx1) * (.5F*t) + cx0;
        // y2 = ((cy3 * (.5F*t) + cy2) * (.5F*t) + cy1) * (.5F*t) + cy0;
        x2 = p[1].x * t;
        y2 = p[1].y * t;

        Point2D A = tcalc(P[0], P[1], t), B = tcalc(P[2], P[3], t), C = tcalc(
                P[1], P[2], t), A1 = tcalc(A, C, t), B1 = tcalc(C, B, t);

        g.setColor(Color.red);
        g.drawLine(iX(x0), iY(y0), iX(x), iY(y));
        // paint(g);
        g.setColor(Color.green);
        g.drawLine(iX(A.x), iY(A.y), iX(C.x), iY(C.y));
        g.drawLine(iX(C.x), iY(C.y), iX(B.x), iY(B.y));
        g.setColor(Color.blue);
        g.drawLine(iX(A1.x), iY(A1.y), iX(B1.x), iY(B1.y));
    }
}

所以我知道我不应该在这些方法中绘画,而应该在绘画中绘画。然而,我有 5 个这样的函数,我不知道如何将它们放入绘图中,如果我更改其他方法来更新,它永远不会删除用户在我想继续下一个时单击的点点的选择。您可以看到我尝试放入一个基本的摆动计时器,但我什至不确定这是否适用于动画的这种情况。

有什么方法可以让它在贝塞尔函数内部工作吗?我只是不知道如何才能把拉绳拿出来。我的第 5 阶有大约 11 个中点被不断计算。显然,我对java图形这部分的理解充其量是不稳定的,所以任何正确方向的观点都将不胜感激。如果我在研究中发现任何内容,我会更新问题。

感谢您的任何帮助。

So at the moment I'm trying to animate different orders of bezier curves and the midpoints that make them up, but I am pretty new to graphics in Java. I understand how paint and repaint work but I can't figure out how to get out of this situation.

The bezier curve points are decided by user clicks here, and repaint() is called at the mouseEvent.

public void paint(Graphics g) {
    initgr();
    int left = iX(-rWidth / 2), right = iX(rWidth / 2), bottom = iY(-rHeight / 2), top = iY(rHeight / 2);
    g.drawRect(left, top, right - left, bottom - top);

    for (int i = 0; i < np; i++) {
        // Show tiny rectangle around point:
        g.drawRect(iX(P[i].x) - 2, iY(P[i].y) - 2, 4, 4);
        if (i > 0)
            // Draw line P[i-1]P[i]:
            g.drawLine(iX(P[i - 1].x), iY(P[i - 1].y), iX(P[i].x),
                    iY(P[i].y));
    }

    if (np == 2 && order == 1)
        bezier1(g, P, gran);
    if (np == 3 && order == 2)
        bezier2(g, P, gran);
    if (np == 4 && order == 3)
        bezier3(g, P, gran);
    if (np == 5 && order == 4)
        bezier4(g, P, gran);
    if (np == 6 && order == 5)
        bezier5(g, P, gran);
}

The functions called at the bottom go to the calculated and drawn bezier curves here.

void bezier3(Graphics g, Point2D[] p, int n) {
    javax.swing.Timer timer = new javax.swing.Timer(100,
            new TimerListener());
    timer.setDelay(39);
    timer.start();
    float dt = 1.0F / n, cx3 = -p[0].x + 3 * (p[1].x - p[2].x) + p[3].x, cy3 = -p[0].y
            + 3 * (p[1].y - p[2].y) + p[3].y, cx2 = 3 * (p[0].x - 2
            * p[1].x + p[2].x), cy2 = 3 * (p[0].y - 2 * p[1].y + p[2].y), cx1 = 3 * (p[1].x - p[0].x), cy1 = 3 * (p[1].y - p[0].y), cx0 = p[0].x, cy0 = p[0].y, x = p[0].x, y = p[0].y, x0, y0, x2, y2;
    for (int i = 1; i <= n; i++) {

        float t = i * dt;

        x0 = x;
        y0 = y;
        x = ((cx3 * t + cx2) * t + cx1) * t + cx0;
        y = ((cy3 * t + cy2) * t + cy1) * t + cy0;
        // x2 = ((cx3 * (.5F*t) + cx2) * (.5F*t) + cx1) * (.5F*t) + cx0;
        // y2 = ((cy3 * (.5F*t) + cy2) * (.5F*t) + cy1) * (.5F*t) + cy0;
        x2 = p[1].x * t;
        y2 = p[1].y * t;

        Point2D A = tcalc(P[0], P[1], t), B = tcalc(P[2], P[3], t), C = tcalc(
                P[1], P[2], t), A1 = tcalc(A, C, t), B1 = tcalc(C, B, t);

        g.setColor(Color.red);
        g.drawLine(iX(x0), iY(y0), iX(x), iY(y));
        // paint(g);
        g.setColor(Color.green);
        g.drawLine(iX(A.x), iY(A.y), iX(C.x), iY(C.y));
        g.drawLine(iX(C.x), iY(C.y), iX(B.x), iY(B.y));
        g.setColor(Color.blue);
        g.drawLine(iX(A1.x), iY(A1.y), iX(B1.x), iY(B1.y));
    }
}

So I know I shouldn't be drawing inside of these methods, but rather in paint. However, I have 5 of these functions that I'm not sure how to put in paint, and if I change the other method to update, it's just never going to erase the points the user clicked when I want to move on to the next selection of points. You can see I tried to put a basic swing timer in, but I'm not even sure if that will work in this situation for the animation.

Is there any way to get this to work inside of the bezier functions? I just don't see how I can get the drawlines out. My 5th order one has something like 11 midpoints being constantly calculated. Obviously, my understanding of this part of java graphics is shaky at best, so any point in the right direction would be greatly appreciated. If I find anything in my research I will update the question.

Thanks for any help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晨与橙与城 2024-12-20 02:40:39

忘记计时器。尝试使用paintComponent。

面向对象将有助于保持概览,简化变量的数量。

  • 使用 Paint(Graphics) {} 和 onMouse(MouseEvent){} 创建基类贝塞尔曲线。
  • 导出 Bezier1、~2、~3 等。
  • 并且有变量 Bezier bezier2 = new Bezier2(); ...
  • 并在您的paintCompont中调用bezier2.paint(g)。

然后在鼠标处理中尝试 repaint(10L) 左右。实验学习(paintImmediate等)。

Forget the timer. Try paintComponent.

Object Oriented would help keeping an overview, simplifying the number of variables.

  • Make a base class Bezier with a paint(Graphics) {} and onMouse(MouseEvent){}.
  • Derive Bezier1, ~2, ~3 and so on.
  • And have variables Bezier bezier2 = new Bezier2(); ...
  • And in your paintCompont call bezier2.paint(g).

Then try repaint(10L) or so in your mouse handling. Experiment to learn (paintImmediate and so on).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文