This post is a suite to an answer I made to question: Transforming a shape
Here is the image I want:
Here is the image a simple program produces, as you can see the text is rotated. I want horizontal text:
The canvas is scaled, translated, rotated to do the drawing, so the text is not displayed horizontaly and the font size need to be extremely reduced (1.4). The program is wrote in Java (awt and JavaFX) but the problem is not language or technology relevant, so any suggestion is welcome.
Here is the simple program:
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();
}
}
In the program used to display first image (the goal), I use two canvases, the first canvas is scaled, translated, rotated to do the drawing without any text and the second canvas is used only to draw labels horizontally, using java.awt.geom.AffineTransform
to compute coordinates to match the item displayed in the first canvas. Both canvases are displayed superposed, they are transparent.