Manipulați Arc cu mouse-ul (JavaFX 2)

Am o problemă pentru a manipula o formă Arc în javafx cu evenimente de tragere mouse-ului

Am un Arc definit cu următoarele parametri:

  • radiusX și radiusY: raza orizontală și verticală a elipsei totale a cărui arc este o secțiune parțială
  • centerX, centerY: punctul central al arcului
  • startAngle: unghiul de pornire al arcului (în raport cu axa orizontală)
  • lungimea: măsurarea unghiulară a arcului în grade

Deci, ceea ce am nevoie este de a face unghiul de pornire a arcului "urmați" mișcarea mouse-ului în timp ce trageți:

când utilizatorul apasă pe punctul de pornire al arcului (situat pe startAngle) și în timp ce trageți mouse-ul trebuie să calculez noul unghi de pornire format de axa orizontală, iar linia de la centru la poziția mouse-ului

Practic, problema este de a calcula unghiul de pornire a arcului dat un punct (poziția mouse-ului) și ceilalți parametri (centrul, axa majoră și cea minoră)

Ceea ce fac actuallyally este calculul unghiului cu funcția Math.atan2

newStartAngle = atan2 (xMouse, yMouse) (presupuneți centrul x, y la 0,0)

dar funcționează numai dacă arcul este circular (radiusX = radiusY)

Un alt mod de a pune este: Am nevoie ca punctul de pornire a arcului să fie mereu pe linie de la centru la poziția mouse-ului (deci trebuie să actualizez continuu unghiul de pornire pentru a face să urmeze mișcarea de rotație a mouse-ului). (sper că am făcut-o puțin clar)

Iată sursa completă a unui eșantion

import javafx.stage.Stage;
...

public class Main extends Application {

@Override
public void start(Stage primaryStage) {
    Pane pane = new Pane();

    Group designer = createDesigner();
    designer.setLayoutX(100);
    designer.setLayoutY(200);
    pane.getChildren().add(designer);

    Scene sc = new Scene(pane, 600, 600);
    primaryStage.setScene(sc);
    primaryStage.show();
}

public static final double RX = 100;
public static final double RY = 50;
public static final double S_ANGLE = 45;
public static final double ARC_LENGTH = 90;

private Arc arc;
private Circle handle;
private Line connection;
double xMouse,yMouse;

public Group createDesigner() {

    arc = new Arc();        
    arc.setRadiusX(RX);
    arc.setRadiusY(RY); 
    arc.setStartAngle(S_ANGLE);
    arc.setLength(ARC_LENGTH);
    arc.setFill(Color.LIGHTBLUE);
    arc.setType(ArcType.ROUND);

    handle = new Circle();
    handle.setRadius(5);    
    handle.setStroke(Color.BLACK);
    handle.setFill(Color.TRANSPARENT);

    handle.setCenterX(
            RX * Math.cos(Math.toRadians(S_ANGLE))
        );
    handle.setCenterY(
            -RY * Math.cos(Math.toRadians(S_ANGLE))
        );

    connection = new Line();
    connection.startXProperty().bind(arc.centerXProperty());
    connection.startYProperty().bind(arc.centerYProperty());
    connection.endXProperty().bind(handle.centerXProperty());
    connection.endYProperty().bind(handle.centerYProperty());

    handle.setOnMouseDragged(new EventHandler() {

        @Override
        public void handle(MouseEvent event) {

            xMouse = event.getX();
            yMouse = event.getY();

            handle.setCenterX(xMouse);
            handle.setCenterY(yMouse);


           double angleInRadians = Math.atan2(-yMouse, xMouse);

            arc.setStartAngle(Math.toDegrees(angleInRadians));

        }

    });

    return new Group(arc, connection, handle);

}

public static void main(String[] args) {
    launch(args);
}

}

Multumesc anticipat

1

1 răspunsuri

bine am rezolvat-o, sunt suficiente pentru a împărți xMouse și yMouse prin toporul principal și minor pentru a face să funcționeze

newStartAngle = Math.atan2(-yMouse/radiusY, xMouse/radiusX) 
//assume center x, y at 0,0
1
adăugat