java 仿射变换_java – 仿射变换图形,而不是文本和标签

这是我想要的图像:

这是一个简单程序生成的图像,因为您可以看到文本是旋转的.我想要水平文字:

画布被缩放,平移,旋转以进行绘制,因此文本不会按水平显示,并且字体大小需要极大地减小(1.4).该程序是用Java(awt和JavaFX)编写的,但问题不是语言或技术相关,所以任何建议都是受欢迎的.

这是一个简单的程序:

import javafx.application.Application;

import javafx.geometry.VPos;

import javafx.scene.Scene;

import javafx.scene.canvas.Canvas;

import javafx.scene.canvas.GraphicsContext;

import javafx.scene.layout.BorderPane;

import javafx.scene.paint.Color;

import javafx.scene.text.Font;

import javafx.scene.text.TextAlignment;

import javafx.stage.Stage;

public class TransRotScale extends Application {

private static void drawGraph( GraphicsContext g ) {

//---

g.scale( 10.0, 10.0 );

g.rotate( Math.toDegrees( Math.atan2( -15.0, 40.0 )));

g.translate( -8, -10 );

//---

g.setStroke( Color.DARKRED );

g.setLineWidth( LINE_WIDTH );

g.strokeLine( 10, 20, 10, 30 );

g.strokeLine( 10, 30, 50, 30 );

g.strokeLine( 50, 30, 50, 35 );

//---

g.setFill( Color.BLACK );

g.fillOval( 50-ENDPOINT_RADIUS, 35-ENDPOINT_RADIUS,

ENDPOINT_DIAMETER, ENDPOINT_DIAMETER );

g.fillOval( 10-ENDPOINT_RADIUS, 20-ENDPOINT_RADIUS,

ENDPOINT_DIAMETER, ENDPOINT_DIAMETER );

//---

g.setFill( Color.LIGHTSALMON );

g.fillOval( 10-ENDPOINT_RADIUS, 30-ENDPOINT_RADIUS,

ENDPOINT_DIAMETER, ENDPOINT_DIAMETER );

g.fillOval( 50-ENDPOINT_RADIUS, 30-ENDPOINT_RADIUS,

ENDPOINT_DIAMETER, ENDPOINT_DIAMETER );

//---

g.setStroke( Color.DARKGRAY );

g.setFont( Font.font( Font.getDefault().getFamily(), 1.4 ));

g.setLineWidth( 0.1 );

g.setTextAlign( TextAlignment.CENTER );

g.setTextBaseline( VPos.BOTTOM );

g.strokeText( "[10, 20]", 10, 20-ENDPOINT_RADIUS );

g.setTextBaseline( VPos.TOP );

g.strokeText( "[10, 30]", 10, 30+ENDPOINT_RADIUS );

g.setTextBaseline( VPos.BOTTOM );

g.strokeText( "[50, 30]", 50, 30-ENDPOINT_RADIUS );

g.setTextBaseline( VPos.TOP );

g.strokeText( "[50, 35]", 50, 35+ENDPOINT_RADIUS );

}

@Override

public void start( Stage primaryStage ) throws Exception {

BorderPane bp = new BorderPane();

Canvas canvas = new Canvas( 540, 240 );

bp.setCenter( canvas );

drawGraph( canvas.getGraphicsContext2D());

primaryStage.setScene( new Scene( bp ));

primaryStage.centerOnScreen();

primaryStage.show();

}

public static final double ENDPOINT_RADIUS = 2.0;

public static final double ENDPOINT_DIAMETER = 2.0*ENDPOINT_RADIUS;

public static final double LINE_WIDTH = 1.0;

public static void main( String[] args ) {

launch();

}

}

在用于显示第一个图像(目标)的程序中,我使用两个画布,第一个画布被缩放,平移,旋转以进行绘制而没有任何文本,第二个画布仅用于水平绘制标签,使用java.awt .geom.AffineTransform计算坐标以匹配第一个画布中显示的项目.两幅画布都是叠加显示的,它们是透明的.

解决方法:

如果我理解的话,这就是Alexander Kirov的建议:

import javafx.application.Application;

import javafx.geometry.VPos;

import javafx.scene.Scene;

import javafx.scene.layout.Pane;

import javafx.scene.paint.Color;

import javafx.scene.shape.Circle;

import javafx.scene.shape.Polyline;

import javafx.scene.text.Font;

import javafx.scene.text.Text;

import javafx.scene.text.TextAlignment;

import javafx.stage.Stage;

public class TransRotScal extends Application {

@Override

public void start( Stage primaryStage ) throws Exception {

Pane pane = new Pane();

pane.setScaleX( 10.0 );

pane.setScaleY( 10.0 );

pane.setRotate( theta );

pane.setTranslateX( 468.0 );

pane.setTranslateY( 152.0 );

Polyline line = new Polyline( 10,20, 10,30, 50,30, 50,35 );

line.setStroke( Color.DARKRED );

Circle c0 = new Circle( 10, 20, 2, Color.BLACK );

Circle c1 = new Circle( 10, 30, 2, Color.LIGHTSALMON );

Circle c2 = new Circle( 50, 30, 2, Color.LIGHTSALMON );

Circle c3 = new Circle( 50, 35, 2, Color.BLACK );

Text t0 = createText( 10, 20, "[10,20]", VPos.BOTTOM );

Text t1 = createText( 10, 30, "[10,30]", VPos.TOP );

Text t2 = createText( 50, 30, "[50,30]", VPos.BOTTOM );

Text t3 = createText( 50, 35, "[50,35]", VPos.TOP );

pane.getChildren().addAll( line, c0, c1, c2, c3, t0, t1, t2, t3 );

primaryStage.setScene( new Scene( pane ));

primaryStage.centerOnScreen();

primaryStage.setWidth ( 580 );

primaryStage.setHeight( 280 );

primaryStage.show();

}

private Text createText( int x, int y, String label, VPos vPos ) {

Text text = new Text( x, y, label );

text.setFill( Color.DARKGRAY );

text.setFont( Font.font( Font.getDefault().getFamily(), 1.4 ));

text.rotateProperty().set( -theta );

text.textAlignmentProperty().setValue( TextAlignment.CENTER );

text.setX( text.getX() - text.getBoundsInLocal().getWidth()/2.0);

text.textOriginProperty().set( vPos );

if( vPos == VPos.BOTTOM ) {

text.setY( text.getY() - 2 );

}

else {

text.setY( text.getY() + 2 );

}

return text;

}

private final double theta = Math.toDegrees( Math.atan2( -15.0, 40.0 ));

public static void main( String[] args ) {

launch();

}

}

它工作但它使用Node代替画布,调整文本的值是通过迭代尝试获得的(很多!);我不知道如何计算它们.

亚历山大,你可以编辑这篇文章或发表你自己的文章来完成它,在后面的例子中我将删除它.

结果如下,请注意光盘周围文字的近似位置:

标签:java,transform,javafx-2,java-canvas

来源: https://codeday.me/bug/20190709/1410531.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值