2013-04-01 1 views
4

이 게시물이 내가 질문에 만든 대답 모음입니다 레이블 : 내가 원하는 이미지 여기 Transforming a shape아핀하지 텍스트, 그래프 변환 및

된다

여기 The text is horizontal

가있다 간단한 프로그램이 생성하는 이미지. 텍스트가 회전 된 것을 볼 수 있습니다. 나는 수평 텍스트를 원하는 :

The text is rotated

캔버스 도면을 회전, 변환, 스케일링, 그래서 텍스트가 수평입니다 표시되지 않고 글꼴 크기가 매우 감소 될 (1.4)가 필요합니다. 이 프로그램은 Java (awt 및 JavaFX)로 작성되었지만 문제는 언어 또는 기술과 관련이 없으므로 어떠한 제안도 환영합니다. 여기

단순 프로그램 : 제 화상 (목표)를 표시하는 데 사용되는 프로그램, I는 두 캔버스를 사용

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을 사용하여 레이블을 가로로 그릴 때만 두 번째 캔버스가 사용됩니다. 두 캔버스가 겹쳐서 표시되며 투명합니다.

+0

암 : 여기

이 결과, 디스크 주변 텍스트의 approximative 위치를 확인합니다. JavaFX의 노드 클래스의? 이것은 원형의 중심을 통해 선으로 설정할 수있는 속성이며 텍스트 노드의 속성을 일부 값으로 바인딩합니다. –

+0

@AlexanderKirov : 답변을 게시했습니다. 검토해주십시오. – Aubin

답변

1

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(); 
    } 
} 

그것은 작동하지만 캔버스 대신에 노드를 사용하고 값이 텍스트가 반복 시도함으로써 얻어진다 조정 (많이!) 나는 그들을 어떻게 계산 해야할지 모르겠다.

알렉산더,이 게시물을 편집하거나 완료하려면 나만의 게시물을 게시 할 수 있습니다. 나중에이를 삭제합니다. 이 노드의 회전축을 정의을 ObjectProperty rotationAxisProperty()에서 볼 않았다

Alexander Kirov answer

0

문자열을 Graphics 객체에 직접 그리는 대신 문자열 대신 GlyphVector를 만들고 Graphics 객체에 그릴 수 있습니까? 이 방법의 장점은 GlyphVector가 캔버스의 회전을 효과적으로 취소하는 데 사용할 수있는 자체 변형을 가질 수 있다는 것입니다. 글리프 생성에 대한 정확한 세부 사항은 기억이 나지 않지만 Font 및 FontRenderContext가 필요합니다. 둘 다 이미 그래픽 컨텍스트에서 사용할 수 있습니다. 내가 잘 이해한다면

+0

제안 해 주셔서 감사합니다. 나는 [알렉산더 키로프] (http://stackoverflow.com/users/1951882/alexander-kirov)의 제안 후에 그것을 공부할 것이다. – Aubin