4

この投稿は、私が質問した答えへのスイートです: Transforming a shape

ここに私が欲しい画像があります:

文字が横長

テキストが回転されていることがわかるように、単純なプログラムが生成する画像を次に示します。横書きのテキストが欲しい:

テキストが回転します

キャンバスは、描画を行うためにスケーリング、移動、回転されるため、テキストは水平方向に表示されず、フォント サイズを大幅に縮小する必要があります (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();
   }
}

最初の画像 (目標) を表示するために使用されるプログラムでは、2 つのキャンバスを使用します。最初のキャンバスは拡大縮小、変換、回転されてテキストなしで描画され、2 番目のキャンバスはラベルを水平に描画するためだけに使用java.awt.geom.AffineTransformされ、座標を計算するために使用されます。最初のキャンバスに表示されるアイテムと一致するようにします。両方のキャンバスが重ねて表示され、透明になっています。

4

2 に答える 2