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
所以,我在程序员的建议下修改了代码,但是箭头的移动是如此令人不快。屏幕->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);
}
}
类箭头扩展了path2d.double{
public ArrowHead() {
double size = Config.ARROW_HEAD_SIZE;
moveTo(0, size);
lineTo(size / 2, 0);
lineTo(size, size);
}
}
1条答案
按热度按时间gkl3eglg1#
因此,旋转将发生在左上角(
0x0
或“原点”)。对于一个组件,这已经被翻译到左上角供您使用。您还需要考虑到转换是复合的,所以您需要确保在完成转换时撤消它们—特别是因为
Graphics
swing中的上下文已共享。。。那会把事情搞砸的。所以。其基本思想是:
将内容转换到要绘制形状的位置
围绕形状的中心旋转上下文,这将“通常”产生所需的结果
重置转换
下面的示例演示了基本思想并使用
Timer
旋转形状你可能还想看一看用一条线连接两个圆,这是一个更复杂的例子,这个概念,但似乎更符合你要实现的