我试图制作可旋转的矩形,但矩形不会显示在我期望的位置。
黑色和蓝色矩形应该围绕红点旋转,但由于某种原因它们偏离中心。红色矩形是黑色矩形所在的位置。
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;
}
}
问题很可能出在getStart或getEnd函数中,但我不知道我哪里出错了。
答案 0 :(得分:3)
你在getStart(int angle)方法中错了,这里:
int angle2 = ( angle + 180 + 45 ) % 360;
您假设每个矩形都是正方形(您添加45°度!)。事实上,如果你使用square(widht = height)你的代码是正确的。 您必须将c的angle2计算为a / b的aTan。
因此,要修复代码,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 );
}
希望我帮助过你!