Я пытаюсь повернуть группу фигур вокруг пользовательской (изменяющейся) точки поворота. Как, например, в CATIA, я хочу иметь возможность щелкнуть одну из этих фигур в группе, чтобы определить точку поворота. Затем я хочу иметь возможность вращать группу вокруг этой точки поворота, перетаскивая мышь по оси x или y. Как и в Catia, я хочу иметь возможность определять новую точку поворота после каждого поворота и вращать группу вокруг этой новой точки поворота в x и y. Однако группа не должна терять прежнюю ориентацию. Проблема в том, что первое вращение работает нормально, но каждое следующее вращение вращается вокруг чего-то, что не определено щелчком мыши.
Теперь, пытаясь это в течение нескольких недель, я думаю, что выяснил, почему это не работает. В документах говорится, что точка поворота установлена относительно начала координат. Поэтому, когда я хочу определить новую опорную точку, координаты точки понимаются относительно начала формы (там, где она начиналась), а не там, где форма в настоящее время находится в результате вращения.
Я пытался сохраните все прошедшие Rotate-Transforms в списке и примените их к новой точке вращения ДО создания нового объекта Rotate и установки его точки вращения. Это тоже не похоже на работу. Я даже не уверен, является ли этот путь правильным.
Может ли кто-нибудь мне помочь? На mousePressedEvent я конвертирую координаты события в координаты сцены, а затем передаю эту информацию вместе со сценой и смарт-группой в свой метод newRotation (). Этот метод затем устанавливает mouseDraggedEvent-Listener. Это повторяется для каждого mousePressedEvent. Ниже мой код:
import application.MouseControl;
import application.SmartGroup;
import javafx.application.Application;
import javafx.geometry.Point3D;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Cylinder;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Sphere;
import javafx.stage.Stage;
public class Test extends Application{
public void start(Stage primaryStage) throws Exception {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
// creating the rectangles
Rectangle rect1 = new Rectangle(100,100,200,200);
Rectangle rect2 = new Rectangle(100,100,200,200);
Circle sphere1 = new Circle(100,100,10);
Cylinder cli = new Cylinder(20,100);
cli.setTranslateX(200);
cli.setTranslateY(200);
//spere1.setTranslateX(100);
//spere1.setTranslateY(100);
// setting the color and stroke for the Rectangles
rect1.setFill(Color.LIMEGREEN);
rect2.setFill(Color.DARKGREY);
rect1.setStroke(Color.BLACK);
rect2.setStroke(Color.BLACK);
// instantiating the Group
SmartGroup root = new SmartGroup();
SmartGroup rotationGroup = new SmartGroup();
SmartGroup stationaryGroup = new SmartGroup();
root.getChildren().add(rotationGroup);
root.getChildren().add(stationaryGroup);
stationaryGroup.getChildren().add(rect1);
rotationGroup.getChildren().add(rect2);
rotationGroup.getChildren().add(sphere1);
rotationGroup.getChildren().add(cli);
Scene scene = new Scene(root,500,420, true);
primaryStage.setScene(scene);
primaryStage.setTitle("Rotation");
MouseControl control = new MouseControl();
rect2.setOnMousePressed(event -> {
Point3D eventPoint = new Point3D(event.getX(),event.getY(),event.getZ());
Sphere sphere2 = new Sphere(10);
System.out.println("New sphere at location of pivot point created");
Point3D scenePoint = new Point3D(rect2.localToScene(eventPoint).getX(), rect2.localToScene(eventPoint).getY(), rect2.localToScene(eventPoint).getZ());
sphere2.setTranslateX(scenePoint.getX());
sphere2.setTranslateY(scenePoint.getY());
sphere2.setTranslateZ(scenePoint.getZ());
root.getChildren().add(sphere2);
control.newRotation(rotationGroup, scene, scenePoint);
});
scene.setOnMousePressed(event -> {
Point3D scenePoint = new Point3D(event.getSceneX(), event.getSceneY(), control.getAnchorZ());
control.newRotation(rotationGroup, scene, scenePoint);
});
primaryStage.show();
}
public void startup(String[] args) {
// TODO Auto-generated method stub
launch(args);
}
}
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.EventHandler;
import javafx.geometry.Point3D;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.transform.Rotate;
/**
*
* @author nim
* @description
* This class is used to control the transformation/rotation/zoom of a SmartGroup based on mouse events
*/
public class MouseControl {
private double anchorX, anchorY;
private double anchorZ;
private double anchorAngleX = 0;
private double anchorAngleY = 0;
private EventHandler<MouseEvent> draggHandler;
private Rotate xRotate;
private Rotate yRotate;
private Point3D transformedPoint;
/**
*
* @param group The rotation is applied to this group
* @param scene Mouse-Listeners are attached to this scene
* @param pivotPoint PivotPoint in SceneCoordinates
*/
public void newRotation(SmartGroup group, Scene scene, Point3D pivotPoint) {
setAnchorZ(pivotPoint.getZ());
if (draggHandler != null) {
scene.removeEventHandler(MouseEvent.MOUSE_DRAGGED, draggHandler);
xRotate.angleProperty().unbind();
yRotate.angleProperty().unbind();
}
group.getTransforms().addAll(
xRotate = new Rotate(0, Rotate.X_AXIS),
yRotate = new Rotate(0, Rotate.Y_AXIS)
);
anchorX = pivotPoint.getX();
anchorY = pivotPoint.getY();
anchorAngleX = 0;
anchorAngleY = 0;
xRotate.setPivotX(pivotPoint.getX());
xRotate.setPivotY(pivotPoint.getY());
yRotate.setPivotX(pivotPoint.getX());
yRotate.setPivotY(pivotPoint.getY());
xRotate.setPivotZ(pivotPoint.getZ());
yRotate.setPivotZ(pivotPoint.getZ());
//create new MouseDraggedEvent
DoubleProperty angleX = new SimpleDoubleProperty();
DoubleProperty angleY = new SimpleDoubleProperty();
EventHandler<MouseEvent> mDragged = (draggedEvent -> {
angleX.set(anchorAngleX - (anchorY - draggedEvent.getSceneY()));
angleY.set(anchorAngleY + (anchorX - draggedEvent.getSceneX()));
});
xRotate.angleProperty().bind(angleX);
yRotate.angleProperty().bind(angleY);
scene.setOnMouseDragged(mDragged);
draggHandler = mDragged;
}
public double getAnchorX() {
return anchorX;
}
public void setAnchorX(double anchorX) {
this.anchorX = anchorX;
}
public double getAnchorY() {
return anchorY;
}
public void setAnchorY(double anchorY) {
this.anchorY = anchorY;
}
public double getAnchorZ() {
return anchorZ;
}
public void setAnchorZ(double anchorZ) {
this.anchorZ = anchorZ;
}
public double getAnchorAngleX() {
return anchorAngleX;
}
public void setAnchorAngleX(double anchorAngleX) {
this.anchorAngleX = anchorAngleX;
}
public double getAnchorAngleY() {
return anchorAngleY;
}
public void setAnchorAngleY(double anchorAngleY) {
this.anchorAngleY = anchorAngleY;
}
public EventHandler<MouseEvent> getDraggHandler() {
return draggHandler;
}
public void setDraggHandler(EventHandler<MouseEvent> draggHandler) {
this.draggHandler = draggHandler;
}
public Rotate getxRotate() {
return xRotate;
}
public void setxRotate(Rotate xRotate) {
this.xRotate = xRotate;
}
public Rotate getyRotate() {
return yRotate;
}
public void setyRotate(Rotate yRotate) {
this.yRotate = yRotate;
}
}