Java矩形旋转问题

Java矩形旋转问题,java,swing,awt,Java,Swing,Awt,我正在尝试制作可旋转的矩形,但是这些矩形没有显示在我期望的位置 黑色和蓝色的矩形应该围绕红点旋转,但由于某种原因它们偏离中心。红色矩形是黑色矩形应该在的地方 sscce: package test; import java.awt.Dimension; import javax.swing.JPanel; import javax.swing.JFrame; import java.awt.Graphics; import java.awt.Graphics2D; import java.a

我正在尝试制作可旋转的矩形,但是这些矩形没有显示在我期望的位置

黑色和蓝色的矩形应该围绕红点旋转,但由于某种原因它们偏离中心。红色矩形是黑色矩形应该在的地方

sscce:

package test;

import java.awt.Dimension;
import javax.swing.JPanel;
import javax.swing.JFrame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import javax.swing.SwingUtilities;
import java.util.List;
import java.util.ArrayList;

public class RectangleTest
{
    public RectangleTest()
    {
        SwingUtilities.invokeLater( new Runnable()
        {
            @Override
            public void run()
            {
                JFrame frame = new JFrame( "Rectangle Test" );
                frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

                JPanel panel = new VTPanel();
                frame.add( panel );

                frame.pack();
                frame.setVisible( true );
            }
        });
    }

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

class VTPanel extends JPanel
{
    private List<RotatableRectangle> rectlist;

    public VTPanel()
    {
        int angle = 45;
        Location start = new Location( 200 , 200 );
        int w = 50;
        int h = 25;
        rectlist = new ArrayList<>();
        for( int i=0;i<2;i++)
        {
            rectlist.add( new RotatableRectangle( start , w , h , angle ) );
            angle += angle;
        }       
    }

    @Override
    protected void paintComponent( Graphics g )
    {
        super.paintComponent( g );
        Graphics2D g2 = (Graphics2D) g;

        g2.setColor( Color.BLUE );
        for( RotatableRectangle rr : rectlist )
        {
            g2.draw( rr.getPath() );
            g2.setColor( Color.BLACK );
        }
        g2.setColor(Color.RED);
        g2.fill( new Rectangle2D.Double( 200,200,1,1) );
        g2.draw( new Rectangle2D.Double( 175,187.5,50,25) );
    }

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

class RotatableRectangle
{
    private Path2D path;
    private Location center;
    private int width;
    private int height;

    public RotatableRectangle( Location center, int width , int height , int angle )
    {
        this.center = center;
        this.width = width;
        this.height = height;
        path = createPath( angle );
    }

    public Path2D getPath()
    {
        return path;
    }

    public void setAngle( int angle )
    {
        path = createPath( angle );
    }

    private Path2D createPath( int angle )
    {
        Path2D p = new Path2D.Double( Path2D.WIND_EVEN_ODD );
        boolean flip = false;
        Location start = getStart( angle );
        p.moveTo( start.X , start.Y );
        for( int i=0;i<4;i++)
        {
            int length;
            if( flip )
            {
                length = height;
            }
            else
            {
                length = width;
            }
            Location next = getEnd( length , angle , start );
            p.lineTo( next.X , next.Y);
            angle = ( angle + 90 ) % 360;
            start = next;
            flip = !flip;
        }
        p.closePath();
        return p;
    }

    private Location getStart( int angle )
    {
        double a = width / 2.0;
        double b = height / 2.0;
        double c = Math.sqrt( ( a * a ) + ( b * b ) );
        int angle2 = ( angle + 180 + 45 ) % 360;
        return getEnd( c , angle2 , center );
    }

    private Location getEnd( double length , int angle , Location start )
    {
        int w = (int) Math.round( Math.sin( Math.toRadians( angle ) ) * length );
        int h = (int) Math.round( Math.cos( Math.toRadians( angle ) ) * length );
        int x = start.X + w;
        int y = start.Y - h;        
        return new Location( x , y );
    }
}

class Location
{
    public final int X, Y;

    public Location( int x , int y )
    {
        X = x;
        Y = y;
    }   
}
封装测试;
导入java.awt.Dimension;
导入javax.swing.JPanel;
导入javax.swing.JFrame;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Color;
导入java.awt.geom.Path2D;
导入java.awt.geom.Rectangle2D;
导入javax.swing.SwingUtilities;
导入java.util.List;
导入java.util.ArrayList;
公共类矩形测试
{
公共矩形测试()
{
SwingUtilities.invokeLater(新的Runnable()
{
@凌驾
公开募捐
{
JFrame=新JFrame(“矩形测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel=新的VTPanel();
框架。添加(面板);
frame.pack();
frame.setVisible(true);
}
});
}
公共静态void main(字符串[]args)
{
新矩形测试();
}
}
类VTPanel扩展了JPanel
{
私人名单;
公共事务委员会()
{
内倾角=45;
位置开始=新位置(200200);
int w=50;
int h=25;
rectlist=newarraylist();
对于(int i=0;i您在getStart(int angle)方法中的错误,这里:

int angle2 = ( angle + 180 + 45 ) % 360;
假设每个矩形都是正方形(添加45度!)。事实上,如果使用正方形(widt=高度),则代码是正确的。 你必须计算c的角2作为a/b的角

因此,要修复代码,getStart方法将是:

 private Location getStart( int angle )
        {
            double a = width / 2.0;
            double b = height / 2.0;
            double c = Math.sqrt( ( a * a ) + ( b * b ) );

            int ang= (int) Math.toDegrees(Math.atan( Math.min(a,b)/Math.max(a,b))) ;

            int angle2 = ( angle + 180 + ang ) % 360;
            return getEnd( c , angle2 , center );
        }
希望我能帮助您!

您在getStart(int angle)方法中犯了错误,这里:

int angle2 = ( angle + 180 + 45 ) % 360;
假设每个矩形都是正方形(添加45度!)。事实上,如果使用正方形(widt=高度),则代码是正确的。 你必须计算c的角2作为a/b的角

因此,要修复代码,getStart方法将是:

 private Location getStart( int angle )
        {
            double a = width / 2.0;
            double b = height / 2.0;
            double c = Math.sqrt( ( a * a ) + ( b * b ) );

            int ang= (int) Math.toDegrees(Math.atan( Math.min(a,b)/Math.max(a,b))) ;

            int angle2 = ( angle + 180 + ang ) % 360;
            return getEnd( c , angle2 , center );
        }
希望我能帮助您!

您在getStart(int angle)方法中犯了错误,这里:

int angle2 = ( angle + 180 + 45 ) % 360;
假设每个矩形都是正方形(添加45度!)。事实上,如果使用正方形(widt=高度),则代码是正确的。 你必须计算c的角2作为a/b的角

因此,要修复代码,getStart方法将是:

 private Location getStart( int angle )
        {
            double a = width / 2.0;
            double b = height / 2.0;
            double c = Math.sqrt( ( a * a ) + ( b * b ) );

            int ang= (int) Math.toDegrees(Math.atan( Math.min(a,b)/Math.max(a,b))) ;

            int angle2 = ( angle + 180 + ang ) % 360;
            return getEnd( c , angle2 , center );
        }
希望我能帮助您!

您在getStart(int angle)方法中犯了错误,这里:

int angle2 = ( angle + 180 + 45 ) % 360;
假设每个矩形都是正方形(添加45度!)。事实上,如果使用正方形(widt=高度),则代码是正确的。 你必须计算c的角2作为a/b的角

因此,要修复代码,getStart方法将是:

 private Location getStart( int angle )
        {
            double a = width / 2.0;
            double b = height / 2.0;
            double c = Math.sqrt( ( a * a ) + ( b * b ) );

            int ang= (int) Math.toDegrees(Math.atan( Math.min(a,b)/Math.max(a,b))) ;

            int angle2 = ( angle + 180 + ang ) % 360;
            return getEnd( c , angle2 , center );
        }


希望我能帮助你!

仅供参考,你正在重新实现Java中已经存在的类。请参见矩形、点(vs位置)及其2D版本。我通常使用的位置更广泛,普通矩形类不旋转。你应该在某个点从度切换到弧度或圆(即360度=1圆).360度是4000年前巴比伦日历上的一个人工制品,用于跟踪一年中的某一天(日历是360天)供参考,jere是我为操作
区域
s而准备的软件包:可能对您非常有帮助我想仅供参考,您正在重新实现Java中已经存在的类。参见矩形,点(vs位置),以及它们的2D版本我通常使用的位置更广泛,并且普通矩形类不旋转。您应该在某个点上从度切换到弧度或圆(即360度=1圆)。360度是来自4000年前巴比伦历法的人工制品,用于跟踪一年中的某一天(历法为360天)仅供参考,jere是我为操作
Area
s而编写的包:可能对您非常有帮助我想仅供参考,您正在重新实现Java中已经存在的类。请参见矩形,点(vs位置),以及它们的2D版本我通常使用的位置更广泛,并且普通矩形类不旋转。您应该在某个点上从度切换到弧度或圆(即360度=1圆)。360度是来自4000年前巴比伦历法的人工制品,用于跟踪一年中的某一天(历法为360天)仅供参考,jere是我为操作
Area
s而编写的包:可能对您非常有帮助我想仅供参考,您正在重新实现Java中已经存在的类。请参见矩形,点(vs位置),以及它们的2D版本我通常使用的位置更广泛,并且普通矩形类不旋转。您应该在某个点上从度切换到弧度或圆(即360度=1圆)。360度是来自4000年前巴比伦历法的人工制品,用于跟踪一年中的某一天(历法为360天)仅供参考,jere是我为操作
区域
s:可能对你很有帮助我想我知道它是那样的小东西。谢谢。我知道它是那样的小东西。谢谢。我知道它是那样的小东西。谢谢。我知道它是那样的小东西。谢谢。我知道它是那样的小东西。谢谢。