2013-06-05 148 views
2

我正在创建具有顶点和边的图形。该图是有针对性的,所以边缘被表示为箭头。我的问题是得到箭头的正确坐标。将箭头绘制到圆形

Vertex具有Coordinate(见下文类),而一个EdgeVertex转到另一个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); 
} 

我通过aioobehere接到一个应答箭头代码的要领。

我通过重写EdgepaintComponent功能这个方法:

@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; 
    } 
... 
} 

我的当前输出的屏幕截图:

Directed graph

注有两个箭头从d到E和E到D后者没有显示因为箭头在D的后面。

现在要明确,这个问题是:

paintComponent - 方法,这是我在圆的半径,并与标准化乘以(参见方法)载体。这会给我一个圈的圆周点,但它似乎总是在左上角,我没有得到。我想计算最接近源顶点的圆周上的点。

像这样:

http://www.onemotion.com/flash/sketch-paint/

有什么建议?

回答

2

您可以根据顶点中心的坐标和顶点图像半径计算出箭头端点。如果(XA,YA)和(XB,YB)是两个顶点a和b的中心,并且所述顶点半径为r,然后从一个有向线是可以被表示为

x = xa + t*(xb - xa) 
y = ya + t*(yb - ya) 

绘制为一个参数t从0变化到1。由于吨== 1对应于d = SQRT((XB - XA) +(YB - 雅))的距离,你只需要评估上面的t = r/d和t =(dr)/ d。 (不需要触发。)

+0

这就是我正在做的。如果你看一下'paintComponent'方法,我得到圆的半径并将其与归一化的矢量相乘。这会给我一个圈的圆周点,但似乎总是在左上角。我会澄清这个问题。 – mfaerevaag

+0

@ 7SLEVIN - 我还没有完成所有的代码,但有一点看起来很可疑,即偏移总是沿着对角线(x和y相等),而不管两个顶点的位置在哪里。我建议按照我在答案中描述的方式计算箭头终点,然后使用最初发布的aioobe代码(因为它不处理偏移量)。 –

+0

@TomHopp - 完美!谢谢! – mfaerevaag