在Java中旋转多边形 [英] Rotating a polygon in Java

查看:159
本文介绍了在Java中旋转多边形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写的程序在屏幕上绘制多个星星,并为它们提供随机指示和速度。星星会从面板的边缘反弹并留在里面。我需要让星星在移动时旋转。我尝试了很多东西,我无法弄明白。下面是我用来绘制星星并移动它们的代码。



其他信息:



- 星星在一个名为星星的集合中



- 我写了两个类,Star和MyJPanel



设置点数:(星级)

  for(double current = 0; current< nPoints; current + = 1)
{
i =(int)current;
int [] X = new int [nPoints * 2];
int [] Y = new int [nPoints * 2];
cosX = - (Math.cos(当前*((2 * Math.PI)/(nPoints)))* radius [i%2]);
sinY = - (Math.sin(当前*((2 * Math.PI)/(nPoints)))* radius [i%2]);
X [i] =(int)cosX + x;
Y [i] =(int)sinY + y;
addPoint(X [i],Y [i]);
}

移动方法:(星级)

  public void move(int width,int height)
{
if(location.x< = radius [0] || location .x> = width - radius [0])
{
xIncr = -xIncr;
}

if(location.y< = radius [0] || location.y> = height - radius [0])
{
yIncr = -yIncr;
}
translate(xIncr,yIncr);
location.setLocation(location.x + xIncr,location.y + yIncr);
xInc = xIncr;
}

绘制星星:(在MyJPanel类中)

  public void paintComponent(Graphics g)
{
super.paintComponent(g);

for(int i = 0; i< stars.size(); i ++)
{
g2d =(Graphics2D)g;
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,stars.get(i).getAlpha()));
g2d.setColor(stars.get(i).getColor());
g2d.fillPolygon(stars.get(i));

if(stars.get(i).alpha == 0)
{
stars.remove(stars.indexOf(stars.get(i)));
}
}
}

如果有更多的代码或信息需要请告诉我,谢谢!

解决方案

我想看看

  import java.awt.Color; 
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class RotateShape {

public static void main(String [] args){
new RotateShape();
}

public RotateShape(){
EventQueue.invokeLater(new Runnable(){
@Override
public void run(){
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch(ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex){
ex.printStackTrace();
}

JFrame frame = new JFrame(Testing);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

公共类TestPane扩展JPanel {

私有星级星;
private double rotationDelta = 5d;
private int xDelta = 0;
private int yDelta = 0;

public TestPane(){
star = new Star(50,50);
star.moveLocatioBy(75,75);

随机rnd = new Random();
xDelta = rnd.nextInt(4)+ 1;
yDelta = rnd.nextInt(4)+ 1;

计时器计时器=新计时器(40,新ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
star.moveLocatioBy(xDelta,yDelta) );
Rectangle bounds = star.getBounds();
int x = star.getX();
int y = star.getY();

boolean bounced = false;
if(x< 0){
x = 0;
xDelta * = -1;
bounced = true;
} else if(x + bounds.width> getWidth()){
x = getWidth() - bounds.width;
xDelta * = -1;
bounced = true;
}
if(y <0){
y = 0;
yDelta * = -1;
bounced = true;
}否则if(y + bounds.height> getHeight()){
y = getHeight() - bounds.height;
yDelta * = -1;
bounced = true;
}
if(bounced){
rotationDelta * = -1;
}

star.rotateByDegrees(rotationDelta);
star.setLocation(x,y);
repaint();
}
});
timer.start();

}

@Override
public Dimension getPreferredSize(){
return new Dimension(200,200);
}

@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d =(Graphics2D)g.create();
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING,RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,RenderingHints.VALUE_STROKE_PURE);

Shape shape = star.getTransformedInstance();
g2d.setColor(Color.BLUE);
g2d.fill(形状);
g2d.setColor(Color.RED);
g2d.draw(形状);
g2d.dispose();
}

}

公共类Star扩展Path2D.Double {

private double angle = 0;
private int x = 0,y = 0;

public Star(int width,int height){

double heightPart = height / 3d;
double widthPart = width / 3d;

moveTo(width / 2,0);
lineTo(widthPart * 2,heightPart);
lineTo(width,heightPart);
lineTo(widthPart * 2,height / 2);
lineTo(宽度,高度);

lineTo(width / 2,heightPart * 2);
lineTo(0,height);
lineTo(widthPart,height / 2);
lineTo(0,heightPart);
lineTo(widthPart,heightPart);

closePath();
}

public double getAngle(){
return angle;
}

public int getX(){
return x;
}

public int getY(){
return y;
}

public void moveLocatioBy(int xDelta,int yDelta){
this.x + = xDelta;
this.y + = yDelta;
}

public void rotateByDegrees(double delta){
angle + = delta;
}

public void setLocation(int x,int y){
this.x = x;
this.y = y;
}

public Shape getTransformedInstance(){
AffineTransform at = new AffineTransform();
Rectangle bounds = getBounds();
at.rotate(Math.toRadians(angle),x +(bounds.width / 2),y +(bounds.height / 2));
at.translate(x,y);
返回createTransformedShape(at);
}

}

}



<扩展这个想法并不需要太多,以便每个开始都有自己的delta值和简单的 update 方法(它传递的宽度/高度容器),所以你可以赚很多明星


The program I am writing draws multiple stars on the screen and gives them random directions and speeds. The stars will bounce off the edges of the panel and stay inside. I need to have the stars rotating as they are moving. I have tried so many things and I cannot figure it out. Below is the code I use to draw the stars and move them.

Additional Information:

-the stars are in a collection called "stars"

-there are two classes that I wrote, "Star" and "MyJPanel"

Set the points: (in Star class)

for (double current = 0; current < nPoints; current += 1)
{
    i = (int)current;
    int[] X = new int[nPoints * 2];
    int[] Y = new int[nPoints * 2];
    cosX = -(Math.cos(current*((2*Math.PI)/(nPoints)))*radius[i % 2]);
    sinY = -(Math.sin(current*((2*Math.PI)/(nPoints)))*radius[i % 2]);
    X[i] = (int) cosX+x;
    Y[i] = (int) sinY+y;
    addPoint(X[i], Y[i]);
}

Move method: (in Star class)

public void move(int width, int height)
{
    if (location.x <= radius[0] || location.x >= width - radius[0])
    {
        xIncr = -xIncr;
    }

    if (location.y <= radius[0] || location.y >= height - radius[0])
    {
        yIncr = -yIncr;
    }
    translate(xIncr, yIncr);
    location.setLocation(location.x + xIncr, location.y + yIncr);
    xInc = xIncr;
}

Paint the stars: (in MyJPanel class)

public void paintComponent(Graphics g)
{
    super.paintComponent(g);

        for(int i = 0; i < stars.size(); i++)
    {
        g2d = (Graphics2D) g;
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, stars.get(i).getAlpha()));
        g2d.setColor(stars.get(i).getColor());
        g2d.fillPolygon(stars.get(i));

        if(stars.get(i).alpha == 0)
        {
            stars.remove(stars.indexOf(stars.get(i)));
        }
    }
}

If any more code or information is needed please let me know, thank you!

解决方案

I would have a look at Working with Geometry and Transforming Shapes, Text, and Images

Basically, I've created a custom Path2D shape which represents my start. This class carries some additional information with, included it's x/y offset and rotation. It then provides a helper method to create a transformed instance of this shape based on these properties, for example...

public Shape getTransformedInstance() {
    AffineTransform at = new AffineTransform();
    Rectangle bounds = getBounds();
    at.rotate(Math.toRadians(angle), x + (bounds.width / 2), y + (bounds.height / 2));
    at.translate(x, y);
    return createTransformedShape(at);
}

Basically, this is where the magic happens.

There is a simple Swing Timer which applies a delta to the position and rotation.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class RotateShape {

    public static void main(String[] args) {
        new RotateShape();
    }

    public RotateShape() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private Star star;
        private double rotationDelta = 5d;
        private int xDelta = 0;
        private int yDelta = 0;

        public TestPane() {
            star = new Star(50, 50);
            star.moveLocatioBy(75, 75);

            Random rnd = new Random();
            xDelta = rnd.nextInt(4) + 1;
            yDelta = rnd.nextInt(4) + 1;

            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    star.moveLocatioBy(xDelta, yDelta);
                    Rectangle bounds = star.getBounds();
                    int x = star.getX();
                    int y = star.getY();

                    boolean bounced = false;
                    if (x < 0) {
                        x = 0;
                        xDelta *= -1;
                        bounced = true;
                    } else if (x + bounds.width > getWidth()) {
                        x = getWidth() - bounds.width;
                        xDelta *= -1;
                        bounced = true;
                    }
                    if (y < 0) {
                        y = 0;
                        yDelta *= -1;
                        bounced = true;
                    } else if (y + bounds.height > getHeight()) {
                        y = getHeight() - bounds.height;
                        yDelta *= -1;
                        bounced = true;
                    }
                    if (bounced) {
                        rotationDelta *= -1;
                    }

                    star.rotateByDegrees(rotationDelta);
                    star.setLocation(x, y);
                    repaint();
                }
            });
            timer.start();

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
            g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

            Shape shape = star.getTransformedInstance();
            g2d.setColor(Color.BLUE);
            g2d.fill(shape);
            g2d.setColor(Color.RED);
            g2d.draw(shape);
            g2d.dispose();
        }

    }

    public class Star extends Path2D.Double {

        private double angle = 0;
        private int x = 0, y = 0;

        public Star(int width, int height) {

            double heightPart = height / 3d;
            double widthPart = width / 3d;

            moveTo(width / 2, 0);
            lineTo(widthPart * 2, heightPart);
            lineTo(width, heightPart);
            lineTo(widthPart * 2, height / 2);
            lineTo(width, height);

            lineTo(width / 2, heightPart * 2);
            lineTo(0, height);
            lineTo(widthPart, height / 2);
            lineTo(0, heightPart);
            lineTo(widthPart, heightPart);

            closePath();
        }

        public double getAngle() {
            return angle;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

        public void moveLocatioBy(int xDelta, int yDelta) {
            this.x += xDelta;
            this.y += yDelta;
        }

        public void rotateByDegrees(double delta) {
            angle += delta;
        }

        public void setLocation(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public Shape getTransformedInstance() {
            AffineTransform at = new AffineTransform();
            Rectangle bounds = getBounds();
            at.rotate(Math.toRadians(angle), x + (bounds.width / 2), y + (bounds.height / 2));
            at.translate(x, y);
            return createTransformedShape(at);
        }

    }

}

It wouldn't take a lot to expand this idea so that each start had it's own delta values and simple update method (which passed in the width/height of the Container), so you could make lots-o-stars

这篇关于在Java中旋转多边形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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