【问题标题】:Moving Shapes along an arc path with java graphics使用 java 图形沿弧形路径移动形状
【发布时间】:2012-02-11 05:27:52
【问题描述】:

请原谅我的天真,这是我第一次来这里,也是第一次在 java 中处理图形动画。我正在尝试完成沿某种弧线移动的星形动画(尝试模拟二维轨道)。轨道动作与计时器一起使用来为星星设置动画。

简单地说,我在 jpanel 的不同位置画了几颗星星。星星 y 位置的平移取决于该星星与 x 下降轴的距离,x 下降轴初始化为 300(jpanel 的中心)。恒星越接近下降点,它们的 y 位置变化就越小。当一颗星星到达或经过面板的右侧(或消失)时,在其原始 y 位置重置到左侧(丑陋,我知道)。我选择这样做是因为星星是随机放置的。我不能让所有的星星都以相同的 dy 开头,如果是这样,所有的星星都会沿着自己的弧线移动。

但是,当我运行它时,在第三遍之后,所有星星的 x 位置变得更小(进入负范围并且不在视野范围内)。欢迎任何有关完成原始任务的更好方法的建议。谢谢。

private Action orbit = new AbstractAction() {

    int declineAxis = 300; //if a stars top left x is greater than this, move downwards
    double distFromDecline;
    AffineTransform at = new AffineTransform();

    @Override
    public void actionPerformed(ActionEvent ae) {
        for (int i = 0; i < 12; i++) {
            distFromDecline = Math.abs(declineAxis - stars.getStar(i).getBounds().getCenterX());
            if (distFromDecline <= 50) {
                if (stars.getStar(i).getBounds().getX() < declineAxis) {
                    at.translate(5, -2);
                } else {
                    at.translate(5, 2);
                }
            } else if (distFromDecline <= 100 && distFromDecline > 50) {
                if (stars.getStar(i).getBounds().getX() < declineAxis) {
                    at.translate(5, -3);
                } else {
                    at.translate(5, 3);
                }
            } else if (distFromDecline <= 200 && distFromDecline > 100) {
                if (stars.getStar(i).getBounds().getX() < declineAxis) {
                    at.translate(5, -4);
                } else {
                    at.translate(5, 4);
                }
            } else if (distFromDecline >200) {
                if (stars.getStar(i).getBounds().getX() < declineAxis) {
                    at.translate(5, -5);
                } else {
                    at.translate(5, 5);
                }
            }
            stars.move(at, i);
        }
    }
};
public class Stars {

private int[] yOrigins;
private Path2D[] stars;
private Random rand = new Random();

public Stars(int n) {
    stars = new Path2D[n];
    yOrigins = new int[n];
    int dx = 700 / n;
    int x = 0;
    for (int i = 0; i < n; i++) {
        int y = rand.nextInt(401);
        generateStar(i, x, y);
        yOrigins[i] = y;
        x += dx;
    }
}

private void generateStar(int i, int x, int y) {
    stars[i] = new Path2D.Double();
    Path2D.Double cur = (Path2D.Double) stars[i];
    cur.moveTo(x, y);
    cur.lineTo(cur.getCurrentPoint().getX() + 6, y - 2);
    cur.lineTo(cur.getCurrentPoint().getX() + 2, cur.getCurrentPoint().getY() - 6);
    cur.lineTo(cur.getCurrentPoint().getX() + 2, cur.getCurrentPoint().getY() + 6);
    cur.lineTo(cur.getCurrentPoint().getX() + 6, cur.getCurrentPoint().getY() + 2);
    cur.lineTo(cur.getCurrentPoint().getX() - 6, cur.getCurrentPoint().getY() + 2);
    cur.lineTo(cur.getCurrentPoint().getX() - 2, cur.getCurrentPoint().getY() + 6);
    cur.lineTo(cur.getCurrentPoint().getX() - 2, cur.getCurrentPoint().getY() - 6);
    cur.closePath();
}

public void paintStars(Graphics2D g) {
    //super.paintComponent(g);
    g.setColor(new Color(246, 246, 255));
    for (int i = 0; i < stars.length; i++) {
        g.fill(stars[i]);
    }
}

public Shape getStar(int i) {
    return stars[i];
}

void move(AffineTransform at, int i) {
    stars[i] = (Path2D) stars[i].createTransformedShape(at);
    System.out.println(i+": " + stars[i].getBounds());
    if(stars[i].getBounds().getX()>700){
        at.translate(-(stars[i].getBounds().x+stars[i].getBounds().getWidth()), yOrigins[i]);
        stars[i] = (Path2D) at.createTransformedShape(stars[i]);
    }
}

}

【问题讨论】:

  • 欢迎来到 SO!为了尽快获得更好的帮助,请发帖SSCCE

标签: java swing graphics awt graphics2d


【解决方案1】:

java.awt.geom.FlatningPathIterator http://docs.oracle.com/javase/6/docs/api/java/awt/geom/FlatteningPathIterator.html

你通过你的弧(或任何其他形状)并使用这些点来定位星星。

您可以在此处使用 stars frm http://java-sl.com/shapes.html

【讨论】:

  • 非常有用,尽管该链接现在只能通过Archive.org 获得。
【解决方案2】:

来自 Sun/Oracle Java2D 演示的WarpImage java2d/demos/Images/WarpImage.java 是使用PathIterator 跟随CubicCurve2D 的一个吸引人的动画示例。您可能会看看它是否提供任何指导。

【讨论】:

  • @stanislavl 感谢两者,使用 PathIterator 解决了我的问题。事先不知道这些功能的使用。
猜你喜欢
  • 2016-08-25
  • 2020-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多