我想用箭头画一条线。该线可以有任何角度。如何在SWT中实现它?
我在AWT
发现了类似的帖子。我想将其转换为SWT
。但是面临将以下方法转换为SWT的问题。特别是在以下行:
at.concatenate(AffineTransform.getRotateInstance(angle));
以下是this post
的方法void drawArrow(Graphics g1, int x1, int y1, int x2, int y2) {
Graphics2D g = (Graphics2D) g1.create();
double dx = x2 - x1, dy = y2 - y1;
double angle = Math.atan2(dy, dx);
int len = (int) Math.sqrt(dx*dx + dy*dy);
AffineTransform at = AffineTransform.getTranslateInstance(x1, y1);
at.concatenate(AffineTransform.getRotateInstance(angle));
g.transform(at);
// Draw horizontal arrow starting in (0, 0)
g.drawLine(0, 0, len, 0);
g.fillPolygon(new int[] {len, len-ARR_SIZE, len-ARR_SIZE, len}, new int[] {0, -ARR_SIZE, ARR_SIZE, 0}, 4);
}
答案 0 :(得分:1)
这里,箭头方向是从线的方向计算的。我还为该线添加了偏移量,因此它没有通过箭头。行程宽度越高,这一点就越明显。
public static void drawArrow(GC gc, int x1, int y1, int x2, int y2, double arrowLength, double arrowAngle) {
double theta = Math.atan2(y2 - y1, x2 - x1);
double offset = (arrowLength - 2) * Math.cos(arrowAngle);
gc.drawLine(x1, y1, (int)(x2 - offset * Math.cos(theta)), (int)(y2 - offset * Math.sin(theta)));
Path path = new Path(gc.getDevice());
path.moveTo((float)(x2 - arrowLength * Math.cos(theta - arrowAngle)), (float)(y2 - arrowLength * Math.sin(theta - arrowAngle)));
path.lineTo((float)x2, (float)y2);
path.lineTo((float)(x2 - arrowLength * Math.cos(theta + arrowAngle)), (float)(y2 - arrowLength * Math.sin(theta + arrowAngle)));
path.close();
gc.fillPath(path);
path.dispose();
}
...
gc.setLineWidth(1);
gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
drawArrow(gc, x1, y1, x2, y2, 8, Math.toRadians(40));
答案 1 :(得分:0)
转换为SWT的答案given here如下所示:
static Path createArrowForLine( Device device, Point fromPoint, double rotationDeg, double length, double wingsAngleDeg ) {
double ax = fromPoint.x;
double ay = fromPoint.y;
double radB = Math.toRadians( -rotationDeg + wingsAngleDeg );
double radC = Math.toRadians( -rotationDeg - wingsAngleDeg );
Path resultPath = new Path( device );
resultPath.moveTo( ( float )( length * Math.cos( radB ) + ax ), ( float )( length * Math.sin( radB ) + ay ) );
resultPath.lineTo( ( float )ax, ( float )ay );
resultPath.lineTo( ( float )( length * Math.cos( radC ) + ax ), ( float )( length * Math.sin( radC ) + ay ) );
return resultPath;
}
SWT Path API使用float
而不是double
s,因此使用强制转换。
要使用上述方法在画布上绘制箭头,您可以使用以下代码:
Canvas canvas = new Canvas( parent, SWT.NONE );
shell.addPaintListener( new PaintListener() {
@Override
public void paintControl( PaintEvent event ) {
event.gc.setBackground( event.display.getSystemColor( SWT.COLOR_RED ) );
Path path = createArrowForLine( event.display, new Point( 100, 100 ), 180, 100, 45 );
event.gc.fillPath( path );
path.dispose();
}
} );