我正在创建带有顶点和边的图。图形是有方向的,因此边用箭头表示。我的问题是得到箭头的正确坐标。
一 Vertex
有一个 Coordinate
(见下面的课程),而 Edge
从一个 Vertex
对另一个 Vertex
. 挑战是用固定半径绘制顶点(见下图)。我很难让箭头指向圆的正确位置。就我现在的代码而言,箭头指向左上角,而不是最近的点。
我有以下绘制箭头的方法:
public static void drawArrow(Graphics g, Color color, int size,
Coordinate from, Coordinate to, Coordinate offset) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(color);
double dx = to.x - from.x, dy = to.y - from.y;
double angle = Math.atan2(dy, dx);
int len = (int) Math.sqrt(dx*dx + dy*dy);
AffineTransform at = AffineTransform.getTranslateInstance(from.x + offset.x, from.y + offset.y);
at.concatenate(AffineTransform.getRotateInstance(angle));
g2.transform(at);
// Draw horizontal arrow starting in (0, 0)
g2.drawLine(0, 0, len, 0);
g2.fillPolygon(new int[] {len, len-size, len-size, len},
new int[] {0, -size, size, 0}, 4);
}
我从艾奥比的回答中得到了箭头密码的要点。
我通过重写 Edge
的 paintComponent
功能:
@Override
public void paintComponent(Graphics g) {
double radius = this.from.getRadius();
Coordinate vector = this.from.getPosition().clone();
vector.normalize();
vector.x = vector.x * radius; vector.y = vector.y * radius;
Coordinate to = new Coordinate(this.to.getPosition().x - vector.x,
this.to.getPosition().y - vector.y);
GraphicsUtils.drawArrow(g, this.color, ARROW_SIZE,
this.from.getPosition(), to,
new Coordinate(radius, radius));
}
作为 drawArrow
方法做了它应该做的,它从a到b画了一个箭头,我想改变我在上面方法中调用它的方式。例如,通过对 drawArrow
方法或类似的东西。
这个 Coordinate
班级:
public class Coordinate {
public double x;
public double y;
...
public void normalize() {
double length = Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2));
this.x = this.x / length;
this.y = this.y / length;
}
...
}
我当前输出的屏幕截图:
注意,从d到e和e到d都有箭头。后者没有显示,因为箭头在d的圆后面。
现在要澄清的是,问题是:
在 paintComponent
-方法,我取圆的半径,并将其与归一化(见方法)向量相乘。这将给我一个圆的圆周点,但似乎总是在左上角的结果,我不明白。我要计算最靠近源顶点的圆周上的点。
像这样:
有什么建议吗?
1条答案
按热度按时间gr8qqesn1#
可以从顶点中心的坐标和顶点图像半径计算箭头端点。如果(xa,ya)和(xb,yb)是两个顶点a和b的中心,并且顶点以半径r绘制,那么从a到be的有向线可以表示为
对于从0到1变化的参数t。因为t==1对应于d=sqrt((xb-xa)2+(yb-ya)2)的距离,所以您只需要计算t=r/d和t=(d-r)/d的上述距离(无需触发。)