在指定点周围旋转Java 2D图形 [英] Rotating Java 2D Graphics Around Specified Point

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

问题描述

我正在编写一个程序,它将绘制围绕中心点旋转的几个形状。结果应该像一个Spirograph。我试图用矩形测试它,但我只能让它们中的两个出现在窗口中。其中一个是它应该在的位置,但是在第一次旋转之后,它将另一个方形投影到窗口的左上角。它应该围绕中心点旋转和拉伸。这是我的代码的一部分。

  import java.awt。*; 
import java.awt.geom.Ellipse2D;

import javax.swing.JPanel;

public class Shapes extends JPanel
{
private double angle;
私有int类型;
private int radius;
私有int重复;

public Shape(int t,int r,int z)
{
type = t;
radius = r;
repeats = z;
angle = 360 /重复;
}

public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d =(Graphics2D)g;

g.setColor(Color.red);

int centerX = getWidth()/ 2;
int centerY = getHeight()/ 2;

double curAngle = 0;

for(int i = 0; i <= repeats; i + = 1)
{
g.setColor(Color.blue);

Rectangle tangle = new Rectangle(0,0,radius,radius);
g2d.rotate(Math.toRadians(curAngle));
g2d.translate(centerX,centerY);
g2d.draw(tangle);
curAngle + =角度;
}

}

解决方案

请记住, translate rotate 正在混合,也就是说,应用它们,它们会加入到当前的转换中。



有很多方法可以实现这一目标,但首先,我们需要制作一份图形上下文。每当你对变换进行了特别的处理时,这是非常重要的,你需要使用 Graphics 上下文的副本,因为这样会使原始图像不受影响(并且不会影响任何可能被绘制的内容)

  Graphics2D g2d =(Graphics2D)g.create(); 
// ...
g2d.dispose();

现在您对 g2d 不会影响 g



的状态现在,我们可以使用变换的复合效果我们的优势

  Rectangle tangle = new Rectangle(0,0,radius,radius); 
//g2d.translate(centerX,centerY);
g2d.rotate(Math.toRadians(angle),centerX,centerY);
g2d.draw(tangle);

所以,所有这些都适用于 angle 复制到每个循环的 Graphics 上下文的副本。定位点设置为 centerX centerY





好的,那看起来不错,但是如果我调整窗口的大小,会发生什么?



好的,不是我期待的。这是由于原因,形状的大小,定位点,旋转,平移偏移等原因的组合,这些都是为了产生效果(尽管很酷)。



好吧,相反,我们可以简单地为每个循环创建一个新的变换,提供我们想要的确切参数,例如...

pre > Graphics2D g2d =(Graphics2D)g.create();
g2d.setColor(Color.blue);

Rectangle tangle = new Rectangle(0,0,radius,radius);
g2d.translate(centerX,centerY);
g2d.rotate(Math.toRadians(curAngle));
g2d.draw(tangle);
curAngle + =角度;
g2d.dispose();

现在产生...





在使用代码时,我注意到当我增加重复次数时,我没有得到期望的结果。

经过同样的挖掘,我改变了

  angle = 360 /重复; 

  angle = 360.d /重复; 

它停止了整数除法问题(并截断了十进制值)并开始产生期望的结果

一个简单的前后比较...


I'm trying to write a program that will draw several shapes rotated around a center point. The result should be something like a Spirograph. I'm trying to test it using rectangles but I can only get two of them to appear in the window. One of them is where it should be, but then after the first rotation it throws the other square way up in the top left corner of the window. It should be rotated and drawn around the center point. Here is a portion of my code.

import java.awt.*;
import java.awt.geom.Ellipse2D;

import javax.swing.JPanel;

public class Shapes extends JPanel
{
private double angle;
private int type;
private int radius;
private int repeats;

public Shapes(int t, int r, int z)
{
   type = t;
   radius = r;
   repeats = z;      
   angle = 360 / repeats;
}

public void paintComponent( Graphics g )
{
  super.paintComponent( g );
  Graphics2D g2d = (Graphics2D)g;

  g.setColor(Color.red);

  int centerX = getWidth()/2;
  int centerY = getHeight()/2;

  double curAngle = 0;

  for(int i=0; i<=repeats; i+=1)
  {
      g.setColor(Color.blue);

      Rectangle tangle = new Rectangle(0, 0, radius, radius);
      g2d.rotate(Math.toRadians(curAngle));
      g2d.translate(centerX, centerY);
      g2d.draw(tangle);
      curAngle += angle;
  }

}

解决方案

Remember, translate and rotate are compounding, that is, each time you apply them, they add to the current transformation.

There are a number of ways you might be able to achieve this, but first, we need to make a copy of the Graphics context. It's kind of important any time you mess with the transform in particular, you do so with a copy of the Graphics context, as this will leave the original unaffected (and won't effect anything that might be painted after)

Graphics2D g2d = (Graphics2D) g.create();
//...
g2d.dispose();

So anything you do to g2d now, won't affect the state of g

Now, we can use the "compounding" effect of a transform to our advantage

Rectangle tangle = new Rectangle(0, 0, radius, radius);
//g2d.translate(centerX, centerY);
g2d.rotate(Math.toRadians(angle), centerX, centerY);
g2d.draw(tangle);

So, all this does is applies the value of angle to the copy of the Graphics context on each loop. The anchor point is set to the centerX and centerY points

Okay, that looks okay, but what happens if I resize the window?

Okay, not really what I was expecting. This occurs for a combination of reasons, the size of the shape, the anchor point, the rotation, the translation offset, these are all compounding to produce the effect (cool though).

Okay, so, instead, we can simply create a new transform for each loop instead, supplying the exact parameters we want, for example...

Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.blue);

Rectangle tangle = new Rectangle(0, 0, radius, radius);
g2d.translate(centerX, centerY);
g2d.rotate(Math.toRadians(curAngle));
g2d.draw(tangle);
curAngle += angle;
g2d.dispose();

This now produces...

While playing around with the code, I noticed that as I increased the number of repeats, I wasn't getting the desired results.

After same digging, I changed

angle = 360 / repeats;

to

angle = 360.d / repeats;

which stopped the integer division issue (and truncating of the decimal values) and started to produce the desired results

A simple before and after comparison...

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

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