gpt4 book ai didi

layout - 如何像 JavaFX 2.0 演示中那样创建视频墙?

转载 作者:行者123 更新时间:2023-12-02 06:57:39 30 4
gpt4 key购买 nike

如何像此处的 JavaFX 2.0 演示那样创建视频墙:

https://www.youtube.com/watch?v=UXSmJYFrulY#t=411

首先,它不一定是视频,也可以是图像。我想要的只是像视频中那样放置节点,i。 e.呈弯曲形状,如圆柱体或球体的内部。

或者该演示的源代码在某处可用?

非常感谢。

最佳答案

我研究并找到了一个非常棒的网站,其中包含相关信息:

http://paulbourke.net/geometry/transformationprojection/

相关部分是坐标系转换,特别是笛卡尔坐标和球坐标之间的转换方程。

double x = r * Math.sin(angle1) * Math.cos(angle2);
double y = r * Math.sin(angle1) * Math.sin(angle2);
double z = r * Math.cos(angle1);

在我下面的示例中,公式中没有使用 y,因为图像行是堆叠的。

注意:通过在从 -Math.PI 到 Math.PI 的 2 个嵌套 for 循环中使用这些公式,您可以围绕球体布置节点。关于整个球体的困难部分是将节点旋转到中心,这是我无法弄清楚的。

因为我不熟悉 Java3D,所以我也查看了 Building a 3D Sample Application .

最后搞了个拼接墙,代码缩减成这样:

public class VideoWall extends Application {

Random rand = new Random();

Group root = new Group();
PerspectiveCamera camera;

private static final double CAMERA_INITIAL_DISTANCE = -850;
private static final double CAMERA_NEAR_CLIP = 0.1;
private static final double CAMERA_FAR_CLIP = 10000.0;

Image[] images = new Image[] {
new Image("http://upload.wikimedia.org/wikipedia/commons/thumb/4/41/Siberischer_tiger_de_edit02.jpg/320px-Siberischer_tiger_de_edit02.jpg"),
new Image("http://upload.wikimedia.org/wikipedia/commons/thumb/e/e7/White_Lion.jpg/320px-White_Lion.jpg"),
new Image("http://upload.wikimedia.org/wikipedia/commons/thumb/4/47/Lion_female.jpg/319px-Lion_female.jpg")

};

public VideoWall(){

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

/**
* Create ImageView with random Image.
* @return
*/
private ImageView createImageView() {

Image image = images[ rand.nextInt(images.length)];

ImageView c = new ImageView( image);

c.setFitWidth(140);
c.setFitWidth(100);
c.setPreserveRatio(true);

return c;
}

@Override
public void start(Stage primaryStage) {

// build camera
camera = new PerspectiveCamera(true);
camera.setNearClip(CAMERA_NEAR_CLIP);
camera.setFarClip(CAMERA_FAR_CLIP);
camera.setTranslateZ(CAMERA_INITIAL_DISTANCE);

// we display any node (imageview, webview, etc)
Node node;

// create a single webview; we only add it once because we don't want to flood youtube
WebView webView = new WebView();
webView.getEngine().load(
"http://www.youtube.com/embed/utUPth77L_o?autoplay=1"
);
webView.setPrefSize(100, 70);

// wall. the degrees depend on the distance, image size, translate start points, etc. so these values were just as they fit
double ringBeginDeg = -30;
double ringEndDeg = 38;

double r = 1300;
double yOffset = 80; // offset per image row
double yOffsetInitial = 120; // initial y offset from "floor"

int count=0;

for( double angle1=Math.toRadians(ringBeginDeg); angle1 <Math.toRadians(ringEndDeg); angle1+=0.08)
{

double angle2 = Math.PI;

for( int i=-3; i <= 3; i++)
{

double x = r * Math.sin(angle1) * Math.cos(angle2);
// double y = r * Math.sin(angle1) * Math.sin(angle2);
double z = r * Math.cos(angle1);

// add 1 webview, the rest imageviews
if( count == 16) {
node = webView;
} else {
node = createImageView();
}

node.setTranslateX(x);
node.setTranslateY(yOffset * i - yOffsetInitial);
node.setTranslateZ(z);

// rotate towards viewer position
Rotate rx = new Rotate();
rx.setAxis(Rotate.Y_AXIS);
rx.setAngle(Math.toDegrees( -angle1));

node.getTransforms().addAll(rx);

root.getChildren().add( node);

count++;
}

}

Scene scene = new Scene(root, 1600, 900, Color.BLACK);

primaryStage.setScene( scene);
primaryStage.show();

scene.setCamera(camera);
}

}

您可以添加您喜欢的任何节点。我添加了一个 youtube webview 进行测试。它播放,但视频没有加载,所以你看到的只是静态噪音(屏幕截图中的灰色方 block )。所以从理论上讲,您可以使用 youtube 视频使节点成为所有 webview,但这意味着充斥 youtube。最好使用一些离线视频。

截图如下:

enter image description here

我还玩弄了完整的 3d 示例并创建了一个戒指。这就是它从外部 View 看起来的样子(始终具有相同的图像):

enter image description here

将相机放在中央,您可以很好地滚动环。

如果有人想玩,here's a quick & dirty gist with the navigable ring .使用鼠标左/右/中键进行导航。

如果你想玩弄一个完整的球体,你可以使用这个:

// full sphere
for (double angle1 = -Math.PI; angle1 <= Math.PI; angle1 += 0.15) {
for (double angle2 = -Math.PI; angle2 <= Math.PI; angle2 += 0.15) {

double x = r * Math.sin(angle1) * Math.cos(angle2);
double y = r * Math.sin(angle1) * Math.sin(angle2);
double z = r * Math.cos(angle1);

c = createImageView();

c.setTranslateX(x);
c.setTranslateY(y);
c.setTranslateZ(z);

Rotate rx = new Rotate();
rx.setAxis(Rotate.Y_AXIS);
rx.setAngle(Math.toDegrees(-angle1));

c.getTransforms().addAll(rx);

world.getChildren().add(c);
}
}

看起来像这样:

enter image description here

但如前所述,我还没有想出如何旋转所有图 block ,使它们朝向中心。他们需要平均分配。但这只是为了好玩和题外话。


因为它是我问题中视频的一部分,所以只需要保留一个平行过渡列表来创建图 block 的“构建”动画。底行现在有反射。

enter image description here

扩展代码:

public class VideoWall extends Application {

Random rand = new Random();

Group root = new Group();
PerspectiveCamera camera;

private static final double CAMERA_INITIAL_DISTANCE = -850;
private static final double CAMERA_NEAR_CLIP = 0.1;
private static final double CAMERA_FAR_CLIP = 10000.0;

Image[] images = new Image[] {
new Image("http://upload.wikimedia.org/wikipedia/commons/thumb/4/41/Siberischer_tiger_de_edit02.jpg/320px-Siberischer_tiger_de_edit02.jpg"),
new Image("http://upload.wikimedia.org/wikipedia/commons/thumb/e/e7/White_Lion.jpg/320px-White_Lion.jpg"),
new Image("http://upload.wikimedia.org/wikipedia/commons/thumb/4/47/Lion_female.jpg/319px-Lion_female.jpg")

};

List<ParallelTransition> transitionList = new ArrayList<>();

public VideoWall(){

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

/**
* Create ImageView with random Image.
* @return
*/
private ImageView createImageView() {

Image image = images[ rand.nextInt(images.length)];

ImageView c = new ImageView( image);

c.setFitWidth(140);
c.setFitWidth(100);
c.setPreserveRatio(true);

return c;
}

@Override
public void start(Stage primaryStage) {

// build camera
camera = new PerspectiveCamera(true);
camera.setNearClip(CAMERA_NEAR_CLIP);
camera.setFarClip(CAMERA_FAR_CLIP);
camera.setTranslateZ(CAMERA_INITIAL_DISTANCE);

// we display any node (imageview, webview, etc)
Node node;

// wall. the degrees depend on the distance, image size, translate start points, etc. so these values were just as they fit
double ringBeginDeg = -30;
double ringEndDeg = 38;

double r = 1300;
double yOffset = 80; // offset per image row
double yOffsetInitial = 120; // initial y offset from "floor"

int min = -3;
int max = 3;

for( double angle1=Math.toRadians(ringBeginDeg); angle1 <Math.toRadians(ringEndDeg); angle1+=0.08)
{

double angle2 = Math.PI;

for( int i=min; i <= max; i++)
{

double x = r * Math.sin(angle1) * Math.cos(angle2);
// double y = r * Math.sin(angle1) * Math.sin(angle2);
double z = r * Math.cos(angle1);

node = createImageView();

node.setTranslateX(x);
node.setTranslateY(yOffset * i - yOffsetInitial);
node.setTranslateZ(z);

// rotate towards viewer position
Rotate rx = new Rotate();
rx.setAxis(Rotate.Y_AXIS);
rx.setAngle(Math.toDegrees( -angle1));

node.getTransforms().addAll(rx);

// reflection on bottom row
if( i==max) {
Reflection refl = new Reflection();
refl.setFraction(0.8f);
node.setEffect(refl);
}

// build the wall using a transition
node.setVisible(false);
transitionList.add( createTransition( node));

root.getChildren().add( node);

}

}

Scene scene = new Scene(root, 1600, 900, Color.BLACK);

primaryStage.setScene( scene);
primaryStage.show();

scene.setCamera(camera);

AnimationTimer timer = createAnimation();
timer.start();

}

private AnimationTimer createAnimation() {

Collections.sort(transitionList, new Comparator<ParallelTransition>() {

@Override
public int compare(ParallelTransition arg0, ParallelTransition arg1) {

// bottom right to top left
Point2D ref = new Point2D(1000,1000);
Point2D pt0 = new Point2D( arg0.getNode().getTranslateX(), arg0.getNode().getTranslateY());
Point2D pt1 = new Point2D( arg1.getNode().getTranslateX(), arg1.getNode().getTranslateY());

return Double.compare(ref.distance(pt0), ref.distance(pt1));

// bottom row first
// return -Double.compare( arg0.getNode().getTranslateY(), arg1.getNode().getTranslateY());

}

});


AnimationTimer timer = new AnimationTimer() {

long last = 0;

@Override
public void handle(long now) {

//if( (now - last) > 1_000_000_000)
if( (now - last) > 40_000_000)
{
if( transitionList.size() > 0) {

ParallelTransition t = transitionList.remove(0);
t.getNode().setVisible(true);
t.play();

}
last = now;

}

if( transitionList.size() == 0) {
stop();
}
}

};

return timer;
}

private ParallelTransition createTransition( final Node node) {

Path path = new Path();
path.getElements().add(new MoveToAbs( node, node.getTranslateX() - 1000, node.getTranslateY() - 900));
path.getElements().add(new LineToAbs( node, node.getTranslateX(), node.getTranslateY()));

Duration duration = Duration.millis(1500);

PathTransition pt = new PathTransition( duration, path, node);

RotateTransition rt = new RotateTransition( duration, node);
rt.setByAngle(720);
rt.setAutoReverse(true);

ParallelTransition parallelTransition = new ParallelTransition();
parallelTransition.setNode(node);
parallelTransition.getChildren().addAll(pt, rt);

return parallelTransition;

}

public static class MoveToAbs extends MoveTo {

public MoveToAbs( Node node, double x, double y) {
super( x - node.getLayoutX() + node.getLayoutBounds().getWidth() / 2, y - node.getLayoutY() + node.getLayoutBounds().getHeight() / 2);
}

}

public static class LineToAbs extends LineTo {

public LineToAbs( Node node, double x, double y) {
super( x - node.getLayoutX() + node.getLayoutBounds().getWidth() / 2, y - node.getLayoutY() + node.getLayoutBounds().getHeight() / 2);
}

}

}

关于layout - 如何像 JavaFX 2.0 演示中那样创建视频墙?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28230755/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com