我有一个对象,比如这个例子中的盒子。我希望这个盒子在Z轴旋转时在球体上以正弦向左移动。但是在盒子做了一条曲线之后,也就是Z轴的旋转回到0。球体不再像开始时那样向下旋转,而是向右向上旋转。
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.Sphere;
import javafx.scene.transform.*;
import javafx.stage.Stage;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import java.util.ArrayList;
public class TestFX extends Application {
public static final float WIDTH = 1400;
public static final float HEIGHT = 1000;
private final ArrayList<String> input = new ArrayList<>();
private final Sphere sphere = new Sphere(500);
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
Flugzeug flieger = new Flugzeug(30, 30, 50);
flieger.setMaterial(new PhongMaterial(Color.GREEN));
flieger.setTranslateZ(330);
flieger.getTransforms().add(new Rotate(20, Rotate.X_AXIS));
sphere.translateZProperty().set(710);
sphere.translateYProperty().set(420);
PhongMaterial phongMaterial = new PhongMaterial();
phongMaterial.setDiffuseMap(new Image(getClass().getResourceAsStream("Earth_diffuse_8k.png")));
sphere.setMaterial(phongMaterial);
PerspectiveCamera camera = new PerspectiveCamera(true);
camera.setFarClip(40000);
Group root = new Group(flieger, sphere);
Scene scene = new Scene(root, WIDTH, HEIGHT, true);
scene.setCamera(camera);
primaryStage.setTitle("FliegenFX");
primaryStage.setScene(scene);
primaryStage.show();
new AnimationTimer() {
@Override
public void handle(long now) {
initGameLogic(flieger);
dreheErde(flieger, sphere);
}
}.start();
scene.setOnKeyPressed(event -> {
String code = event.getCode().toString();
if (!input.contains(code))
input.add(code);
});
scene.setOnKeyReleased(event -> {
String code = event.getCode().toString();
input.remove(code);
});
}
// TODO Erddrehung nach Drehung beibehalten
private void dreheErde(Flugzeug flieger, Sphere erde) {
double rotationFactor = 0.005;
double drehung = flieger.getDrehung() * rotationFactor;
double amplitude = 2;
double frequency = 0.001;
float angle = (float) (Math.sin(drehung * frequency) * amplitude);
Quaternionf quat = new Quaternionf();
Matrix4f matrix4f = new Matrix4f();
Affine affine = new Affine();
quat.rotateY(angle);
quat.rotateZ(angle);
quat.rotateX(-0.001f);
quat.normalize();
quat.get(matrix4f);
float[] matrixArray = new float[16];
matrix4f.get(matrixArray);
double[] matrix = new double[16];
for (int i = 0 ; i < matrixArray.length; i++)
{
matrix[i] = matrixArray[i];
}
affine.append(matrix, MatrixType.MT_3D_4x4, 0);
erde.getTransforms().add(affine);
}
private void initGameLogic(Flugzeug flieger) {
if (input.contains("LEFT")) {
flieger.rotateByZ(-0.5);
}
if (input.contains("RIGHT")) {
flieger.rotateByZ(0.5);
}
}
private class Flugzeug extends Box{
private double drehung = 0;
private Rotate r;
private Transform t = new Rotate();
public Flugzeug(double width, double height, double depth){
super(width, height, depth);
}
public void rotateByZ(double ang){
drehung += ang;
r = new Rotate(ang, Rotate.Z_AXIS);
t = t.createConcatenation(r);
getTransforms().clear();
getTransforms().addAll(t);
}
public double getDrehung() {
return drehung;
}
}
}
我尝试了许多不同的方法与三角,但他们都没有成功。这是例如移动的X轴的领域也根据正弦或减去移动的Y和Z轴的领域作为余弦。
我认为它必须转换成旋转矩阵,但我从来没有矩阵计算。
1条答案
按热度按时间k10s72fa1#
在3d场景中旋转另一个
Group
内的Group
在这种方法中,
Box
示例看起来没有移动,因为它是随着摄像机移动的。摄像机和长方体一起移动,因为它的Group
父节点是随着键盘事件旋转的。Sphere
节点在另一个组中,不受影响。球体本身在Y轴上旋转Java应用程序