我写了一个测试程序,使用AffineTransform绘制箭头。程序以窗口的中心作为箭头的起点,以鼠标的位置作为终点。但是,生成的箭头位置和Angular 不正确。当鼠标位于绿色位置时,正确的箭头位置应如下图中的红色箭头所示。我想知道是什么原因导致箭头画错了。x1c 0d1x的数据
我用来绘制整个箭头的逻辑如下:
首先,我从位置(0,0)开始绘制一条长度为(length - arrowheadLength)的水平线。
的然后,我使用(0,0)作为矩形的左上角,并在将其平移到水平线的右端之前对其应用剪切和旋转。
(剪切)
(旋转)x1c4d 1x(平移)接下来,根据计算出的鼠标和开始矩形位置之间的Angular 旋转整个箭头。
型最后,箭头被平移到开始矩形的位置。
型
下面是绘制箭头的代码:
import javax.swing.*;
import javax.swing.event.MouseInputAdapter;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
class CanvasPane extends JPanel {
Rectangle start = new Rectangle();
Line2D.Double arrowShaft = new Line2D.Double();
Rectangle arrowhead = new Rectangle(new Dimension(16, 16));
double shearMultiplier = 0.5;
double arrowheadLength = arrowhead.width * Math.sqrt(2) * (1 + shearMultiplier);
MouseEvent me;
double length, angle;
CanvasPane() {
setPreferredSize(new Dimension(1000, 600));
addMouseMotionListener(new MouseInputAdapter() {
@Override
public void mouseMoved(MouseEvent e)
{
me = e;
repaint();
}
});
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
start.setBounds(getWidth()/2 - 5, getHeight()/2 - 5, 10, 10);
Graphics2D g2d = (Graphics2D) g;
g2d.fill(start);
if (me != null) {
length = Point.distance(start.getCenterX(), start.getCenterY(), me.getX(), me.getY());
angle = Math.atan2(me.getY() - start.getCenterY(), me.getX() - start.getCenterX());
arrowShaft.setLine(0, 0, length - arrowheadLength, 0);
AffineTransform storedTransform = g2d.getTransform();
AffineTransform AT = new AffineTransform();
AT.translate(start.getCenterX(), start.getCenterY());
AT.rotate(angle);
// For the arrowShaft, it is first rotated and then translated.
g2d.transform(AT);
g2d.draw(arrowShaft);
AT.translate(length - arrowheadLength, 0);
AT.rotate(Math.toRadians(-45));
AT.shear(shearMultiplier, shearMultiplier);
// For the arrowhead, it is first sheared, then rotated, translated, rotated again and finally translated.
g2d.transform(AT);
g2d.draw(arrowhead);
g2d.setTransform(storedTransform);
}
}
}
public class DrawLine {
Container createContentPane() {
JPanel contentPane = new JPanel(new BorderLayout());
contentPane.setOpaque(true);
contentPane.add(new CanvasPane(), BorderLayout.CENTER);
return contentPane;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawLine drawLine = new DrawLine();
frame.setContentPane(drawLine.createContentPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
字符串
你能帮我找出是什么原因导致箭头的位置和Angular 不正确吗?- 谢谢-谢谢
1条答案
按热度按时间lrl1mhuk1#
我会重置箭头的AffineTransform,因为在进行主旋转和平移之前需要对其进行独立的变换(这已经应用于Graphics2D对象)。
字符串
或者,首先变换头部矩形,然后变换图形坐标,然后绘制:
型
无论哪种方式,斜矩形都需要自己的变换。
但话虽如此,我甚至不会为此使用仿射变换,而是使用包含Path2D的
java.awt.geom
库,然后根据需要使用基本几何绘制箭头和箭杆。这样,您仍然可以使用有效的RenderingHints来消除绘制形状的别名:的数据
型
顺便说一句,您将需要学习和使用Java命名约定。变量名都应该以小写字母开始,而类名则以大写字母开头。学习并遵循这一点将使我们更好地理解您的代码,并使您更好地理解其他人的代码。