Polygon arrow = new Polygon();
arrow.addPoint(0, 5);
arrow.addPoint(-5, -5);
arrow.addPoint(5, -5);
AffineTransform tx = new AffineTransform();
double angle = Math.atan2(y2 - y1, x2 - x1);
tx.translate(x2 + Config.VERTEX_RADIUS / 2, y2 + Config.VERTEX_RADIUS / 2);
tx.rotate((angle - Math.PI / 2));
graphics.setColor(Color.BLACK);
graphics.draw(new Line2D.Double(x1, y1, x2, y2));
graphics.setTransform(tx);
graphics.fill(arrow);
屏幕:http://imglink.ru/show-image.php?id=254ac13712ad825a1a1b99181170f747
编辑因此,我根据MadProgrammer的建议更改了代码,但是箭头的移动如此令人不愉快。屏幕-> http://www.imglink.ru/show-image.php?id=f1d6d3dfdb52972d731690e031af7d71
private void drawEdgeLine(Graphics2D graphics, double x1, double y1, double x2, double y2) {
graphics.setColor(Color.BLACK);
graphics.draw(new Line2D.Double(x1, y1, x2, y2));
ArrowHead arrowHead = new ArrowHead();
double length = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
double t1 = Config.VERTEX_RADIUS / length;
double t2 = (length - Config.VERTEX_RADIUS) / length;
double arrowX, arrowY;
if (t1 > t2) {
arrowX = x1 + t1 * (x2 - x1);
arrowY = y1 + t1 * (y2 - y1);
} else {
arrowX = x1 + t2 * (x2 - x1);
arrowY = y1 + t2 * (y2 - y1);
}
double angle = Math.atan2(y2 - y1, x2 - x1);
/*double angleDegrees = Math.toDegrees(angle + Math.PI);
System.out.println(angleDegrees);
if (angleDegrees > 90 && angleDegrees < 270) {
arrowY += Config.ARROW_HEAD_SIZE / 2;
} else {
arrowX -= Config.ARROW_HEAD_SIZE / 2;
}*/
AffineTransform transform = AffineTransform.getTranslateInstance(arrowX, arrowY);
transform.rotate(angle + Math.PI / 2);
arrowHead.transform(transform);
graphics.draw(arrowHead);
}
}
Class ArrowHead扩展Path2D.Double {
public ArrowHead() {
double size = Config.ARROW_HEAD_SIZE;
moveTo(0, size);
lineTo(size / 2, 0);
lineTo(size, size);
}
}
因此,旋转将在左上角(0x0
或“原点”)发生。对于一个组件,已将其翻译到左上角以供说服。
[您还需要考虑到转换是复杂的,因此您需要确保在完成转换后将其撤消-尤其是因为Swing中的Graphics
上下文是共享的……而这确实会使事情搞砸了。 。
所以基本思想是:
下面的示例演示了基本概念,并使用Timer
旋转形状
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.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ArrowHead extends Path2D.Double {
public ArrowHead() {
int size = 10;
moveTo(0, size);
lineTo(size / 2, 0);
lineTo(size, size);
closePath();
}
}
public class TestPane extends JPanel {
private ArrowHead arrow = new ArrowHead();
private double angleOfAttack = 0;
public TestPane() {
Timer timer = new Timer(5, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
angleOfAttack += 0.5;
repaint();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Snap shot the current context
Graphics2D g2d = (Graphics2D) g.create();
// Translate to somewhere you want the arrow painted ...
g2d.translate(50, 50);
// The bounding box of the arrow...
Rectangle bounds = arrow.getBounds();
// A guide, showing where the arrow is been painted without the rotation
g2d.setColor(Color.RED);
g2d.draw(bounds);
// Rotate abount the middle of the arrow...
g2d.rotate(Math.toRadians(angleOfAttack), bounds.width / 2, bounds.height / 2);
g2d.setColor(Color.BLACK);
// Draw the arrow
g2d.fill(arrow);
// Discard the transformations so we don't effect anyone else
g2d.dispose();
}
}
}
您可能还想看一下Connect two circles with a line,它是此概念的更复杂示例,但似乎与您要实现的目标更加一致]]