为了处理项目Rybi的立方体游戏,我必须围绕特定的轴转动立方体,所以问题是如果我绕一个轴转动一个物体,例如90度的Y轴,所以如果我再次绕x轴转动,旋转将在Z轴的方向上,因为X轴取决于Z.
下面,有一段代码说明了我刚才介绍的相同情况。
有没有办法以我想要的方式做事
public class RybiCube extends Application {
final Group root = new Group();
final PerspectiveCamera camera = new PerspectiveCamera(true);
final XformCamera cameraXform = new XformCamera();
public static final double CAMERA_INITIAL_DISTANCE = -1000;
public static final double CAMERA_NEAR_CLIP = 0.1;
public static final double CAMERA_FAR_CLIP = 10000.0;
public void init(Stage primaryStage) {
Box box = new Box();
box.setHeight(70);
box.setWidth(200);
box.setDepth(70);
//box.setRotationAxis(Rotate.Y_AXIS);
//box.setRotate(80);
box.getTransforms().add(new Rotate(90,Rotate.Y_AXIS));
box.getTransforms().add(new Rotate(45,Rotate.X_AXIS));
PhongMaterial material = new PhongMaterial();
material.setDiffuseColor(Color.ORANGE);
material.setSpecularColor(Color.BLACK);
box.setMaterial(material);
root.getChildren().add(box);
buildCamera();
Scene scene = new Scene(root, 600, 600, true);
primaryStage.setScene(scene);
scene.setCamera(camera);
///
primaryStage.setResizable(false);
scene.setFill(Color.rgb(0, 0,0,0.5));
primaryStage.setScene(scene);
}
private void buildCamera() {
root.getChildren().add(cameraXform);
cameraXform.getChildren().add(camera);
camera.setNearClip(CAMERA_NEAR_CLIP);
camera.setFarClip(CAMERA_FAR_CLIP);
camera.setTranslateZ(CAMERA_INITIAL_DISTANCE);
}
public void start(Stage primaryStage)
{
init(primaryStage);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
class XformCamera extends Group {
final Translate tr = new Translate(0.0, 0.0, 0.0);
final Rotate rx = new Rotate(00, Rotate.X_AXIS);
final Rotate ry = new Rotate(10, Rotate.Y_AXIS);
final Rotate rz = new Rotate(0, Rotate.Z_AXIS);
public XformCamera() {
super();
this.getTransforms().addAll(tr, rx, ry, rz);
}
}
答案 0 :(得分:0)
您可以简单地将逆变换应用于轴(使用inverseDeltaTransform
):
public static void addRotate(Node node, Point3D rotationAxis, double angle) {
ObservableList<Transform> transforms = node.getTransforms();
try {
for (Transform t : transforms) {
rotationAxis = t.inverseDeltaTransform(rotationAxis);
}
} catch (NonInvertibleTransformException ex) {
throw new IllegalStateException(ex);
}
transforms.add(new Rotate(angle, rotationAxis));
}
box.getTransforms().add(new Rotate(90,Rotate.Y_AXIS));
addRotate(box, Rotate.X_AXIS, 45);
答案 1 :(得分:0)
以下代码基于3D方向,可能对您的应用很有用。
import javafx.scene.Group;
import javafx.scene.transform.Affine;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class XformOrientation extends Group {
private static final int SIZE = 5;
private Affine affine;
private final List<Double> averageRoll = new ArrayList();
private final List<Double> averagePitch = new ArrayList();
private final List<Double> averageYaw = new ArrayList();
public XformOrientation() {
super();
affine = new Affine();
this.getTransforms().add(affine);
}
/**
* angles in degrees
* @param roll
* @param pitch
* @param yaw
*/
public void processEvent(double roll, double pitch, double yaw) {
double avYaw = average(averageYaw, Math.toRadians(yaw));
double avPitch = average(averagePitch, Math.toRadians(pitch));
double avRoll = average(averageRoll, Math.toRadians(roll));
matrixRotateNode(avRoll, avPitch, avYaw);
}
private void matrixRotateNode(double roll, double pitch, double yaw) {
double mxx = Math.cos(pitch) * Math.cos(yaw);
double mxy = Math.cos(roll) * Math.sin(pitch) +
Math.cos(pitch) * Math.sin(roll) * Math.sin(yaw);
double mxz = Math.sin(pitch) * Math.sin(roll) -
Math.cos(pitch) * Math.cos(roll) * Math.sin(yaw);
double myx = -Math.cos(yaw) * Math.sin(pitch);
double myy = Math.cos(pitch) * Math.cos(roll) -
Math.sin(pitch) * Math.sin(roll) * Math.sin(yaw);
double myz = Math.cos(pitch) * Math.sin(roll) +
Math.cos(roll) * Math.sin(pitch) * Math.sin(yaw);
double mzx = Math.sin(yaw);
double mzy = -Math.cos(yaw) * Math.sin(roll);
double mzz = Math.cos(roll) * Math.cos(yaw);
affine.setToTransform(mxx, mxy, mxz, 0,
myx, myy, myz, 0,
mzx, mzy, mzz, 0);
}
private double average(List<Double> list, double value) {
while (list.size() > SIZE) {
list.remove(0);
}
list.add(value);
return list.stream()
.collect(Collectors.averagingDouble(d -> d));
}
}
作为应用程序,您可以使用
private final XformOrientation world = new XformOrientation();
PhongMaterial whiteMaterial = new PhongMaterial();
whiteMaterial.setDiffuseColor(Color.WHITE);
whiteMaterial.setSpecularColor(Color.LIGHTBLUE);
Box box = new Box(400, 200, 100);
box.setMaterial(whiteMaterial);
world.getChildren().addAll(box);
Runnable runnable = new Runnable() {
@Override
public void run() {
Platform.runLater(() -> {
world.processEvent(getRoll(), getPitch(), getYaw());
});
}
};
getAhrsInfo().rollProperty().addListener((observable, oldValue, newValue) -> runnable.run());
getAhrsInfo().pitchProperty().addListener((observable, oldValue, newValue) -> runnable.run());
getAhrsInfo().yawProperty().addListener((observable, oldValue, newValue) -> runnable.run());