ともさんのHP >プロブラミング >JavaFX >Cameraの扱いかた

JavaFX Cameraの扱いかた

JavaFXでは表示するための視点の位置や方向をCameraで設定します。
カメラからみた映像がSceneに表示されます。
CameraはLigthなどとともにGroupに登録しますが、Sceneにも登録する必要があります。

広告

簡単なプログラム
JavaFX Camera

下のプログラムは単純な カメラ 楽天 設定例です。
6面体とLightとCameraをSceneに置いて、6面体を表示しています。
カメラの視線方向はZ軸方向です。
デフォルトでは6面体とカメラが同じ位置なので、カメラをZ方向に-50移動させ、6面体が視界に入るようにしています。

サンプルプログラム

package tomojavalib.fx;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Point3D;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.LightBase;
import javafx.scene.PerspectiveCamera;
import javafx.scene.PointLight;
import javafx.scene.Scene;
import javafx.scene.SubScene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;

/**単純なJavaFX楽天 プログラム
 *カメラの移動、回転
 * */
public class App15 extends Application {

 public static void main(String[] args) {
  Application.launch(args);
 }
 
 @Override
 public void start(Stage stage) throws Exception {
  Scene scene = make3dScene();
  stage.setScene(scene);
  //タイトルの表示
  stage.setTitle("カメラ試験");
  stage.show();
 }

private Scene make3dScene(){
 Group group = new Group();
 //箱を置く
 Box box = new Box( 10 , 10 , 10 );
 group.getChildren().add( box );
 // カメラを置く
 PerspectiveCamera camera = new PerspectiveCamera( true );
 //方向と位置
 Translate cameratranslate = new Translate(0,0,-50);
 camera.getTransforms().add( cameratranslate );
 //点光源を置く
 LightBase light = new PointLight();
 light.setTranslateX(  30.0 );
 light.setTranslateY( -30.0 );
 light.setTranslateZ( -30.0 );
 group.getChildren().add( light );
 //Sceneの設定
 Scene s3d = new Scene(group, 320, 240);
 s3d.setFill(Color.ALICEBLUE);
 s3d.setCamera( camera );
return s3d;
}
}


カメラの回転と平行移動

下記はカメラをX方向に15度、Y方向に15度回転したのち、Z方向へ‐50平行移動するものです。

 Translate cameratranslate = new Translate(0,0,-50);
 Rotate camerarotateX = new Rotate( 15 , new Point3D( 1 , 0 , 0 ) );
 Rotate camerarotateY = new Rotate( 15 , new Point3D( 0 , 1 , 0 ) );
 camera.getTransforms().add( camerarotateX );
 camera.getTransforms().add( camerarotateY );
 camera.getTransforms().add( cameratranslate );

実行結果はこんな感じになります。
JavaFX回転後に平行移動

回転移動と平行移動の順番が重要で、順序が変わると見え方も変わります。

 Translate cameratranslate = new Translate(0,0,-50);
 Rotate camerarotateX = new Rotate( 15 , new Point3D( 1 , 0 , 0 ) );
 Rotate camerarotateY = new Rotate( 15 , new Point3D( 0 , 1 , 0 ) );
 camera.getTransforms().add( cameratranslate );
 camera.getTransforms().add( camerarotateX );
 camera.getTransforms().add( camerarotateY );

上のように平行移動後に回転移動をすると、6面体が視界の中心からずれてしまいます。
JavaFX平行移動後に回転移動

この理由は、カメラの移動がカメラ自身のローカル座標に従って行われるためです。
下図の左が移動後回転、右が回転後移動です。
camera移動手順

表示対象を常に視解の中心に置く方法

座標a,b,cにある物を視界の中心におさめたい場合、Cameraを下記の順に移動させます。
1、座標a,b,c,へ平行移動
2、見たい角度へ回転移動
3、Z軸マイナス方向へ平行移動

下のサンプルプログラムでは、カメラを6面体と同じ位置に平行移動させたのち、回転移動、Z方向平行移動をしています。
実行結果
常に中心

サンプルプログラム

package tomojavalib.fx;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Point3D;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.LightBase;
import javafx.scene.PerspectiveCamera;
import javafx.scene.PointLight;
import javafx.scene.Scene;
import javafx.scene.SubScene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;

/**単純な Java 楽天 FXプログラム
 *カメラの移動、回転
 * */
public class App15 extends Application {

 public static void main(String[] args) {
  Application.launch(args);
 }
 
 @Override
 public void start(Stage stage) throws Exception {
  Scene scene = make3dScene();
  stage.setScene(scene);
  //タイトルの表示
  stage.setTitle("カメラ試験");
  stage.show();
 }

private Scene make3dScene(){
 Group group = new Group();
 //箱を置く
 Box box = new Box( 10 , 10 , 10 );
 Translate boxtranslate = new Translate(100,100,100);
 box.getTransforms().add( boxtranslate );
 group.getChildren().add( box );
 // カメラを置く
 PerspectiveCamera camera = new PerspectiveCamera( true );
 //方向と位置
 Translate cameratranslate = new Translate(0,0,-50);
 Rotate camerarotateX = new Rotate( 45 , new Point3D( 1 , 0 , 0 ) );
 Rotate camerarotateY = new Rotate( 45 , new Point3D( 0 , 1 , 0 ) );
 camera.getTransforms().add( boxtranslate );
 camera.getTransforms().add( camerarotateX );
 camera.getTransforms().add( camerarotateY );
 camera.getTransforms().add( cameratranslate ); 
 
 //点光源を置く
 LightBase light = new PointLight();
 light.setTranslateX(  30.0 );
 light.setTranslateY( -30.0 );
 light.setTranslateZ( -30.0 );
 group.getChildren().add( light );
 //Sceneの設定
 Scene s3d = new Scene(group, 320, 240);
 s3d.setFill(Color.ALICEBLUE);
 s3d.setCamera( camera );
return s3d;
}
}


カメラの視野角と表示範囲

カメラは自分の座標系を持っており、Z軸方向が視線の中心になります。
見える角度は、

 camera.setFieldOfView( 30. );

で設定します。この場合30度になります。
また、カメラから一定の距離以上、以下の範囲を表示しないことができます。

広告

 camera.setFarClip( 50. );
 camera.setNearClip( 45. );

上の場合では距離50以上と45以下は表示されません
実行するとこうなります。
JavaFX可視範囲


可視範囲を3Dで描くと下図のようになります。四角錐を輪切りにしたような形状の内側が可視範囲。
JavaFXcamera可視範囲


カメラの設定後に位置と方向を変える

回転と平行移動に順序があるなら、一度カメラを設置してから動かすのは大変だなあと思ったのですが...
下記のようにCameraにaddしておいたTranslateやRotateをあとから変更することで移動できました。

 camerarotateX.setAngle( 15. );
 camerarotateY.setAngle( 15. );
 cameratranslate.setZ( -100. );

実行結果
左は追記前で、X,Y方向に45度回転、距離50。右は追記後で、X,Y方向に15度回転、距離100にしています。
JavaFXカメラ回転 JavaFXカメラ移動


サンプルプログラム
下記のように追記しましたが、マウスイベントに組み込めばマウスで視点を操作できるようになります。 (こちら

package tomojavalib.fx;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Point3D;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.LightBase;
import javafx.scene.PerspectiveCamera;
import javafx.scene.PointLight;
import javafx.scene.Scene;
import javafx.scene.SubScene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;

/**単純なJavaFXプログラム
 *カメラの移動、回転
 * */
public class App15 extends Application {

 public static void main(String[] args) {
  Application.launch(args);
 }
 
 @Override
 public void start(Stage stage) throws Exception {
  Scene scene = make3dScene();
  stage.setScene(scene);
  //タイトルの表示
  stage.setTitle("カメラ試験");
  stage.show();
 }

private Scene make3dScene(){
 Group group = new Group();
 //箱を置く
 Box box = new Box( 10 , 10 , 10 );
 Translate boxtranslate = new Translate(100,100,100);
 box.getTransforms().add( boxtranslate );
 group.getChildren().add( box );
 // カメラを置く
 PerspectiveCamera camera = new PerspectiveCamera( true );
 //方向と位置
 Translate cameratranslate = new Translate(0,0,-50);
 Rotate camerarotateX = new Rotate( 45 , new Point3D( 1 , 0 , 0 ) );
 Rotate camerarotateY = new Rotate( 45 , new Point3D( 0 , 1 , 0 ) );
 camera.getTransforms().add( boxtranslate );
 camera.getTransforms().add( camerarotateX );
 camera.getTransforms().add( camerarotateY );
 camera.getTransforms().add( cameratranslate ); 
 //視界の角度
 camera.setFieldOfView( 30. );
 //可視距離の設定
 //camera.setFarClip( 50. );
 //camera.setNearClip( 45. );
 group.getChildren().add( camera ); 
 //点光源を置く
 LightBase light = new PointLight();
 light.setTranslateX(  30.0 );
 light.setTranslateY( -30.0 );
 light.setTranslateZ( -30.0 );
 group.getChildren().add( light );
 //Sceneの設定
 Scene s3d = new Scene(group, 320, 240);
 s3d.setFill(Color.ALICEBLUE);
 s3d.setCamera( camera );

 //カメラの向きと位置を変更
 camerarotateX.setAngle( 15. );
 camerarotateY.setAngle( 15. );
 cameratranslate.setZ( -100. );
return s3d;
}
}


最終更新日: 2017-03-06 12:35:47

ともさんのHP >プロブラミング >JavaFX >Cameraの扱いかた

広告
新着ページ

AIを利用し、衣服のデザイン画から型紙を制作する方法  
2つのアパレル3D技術でひらくオーダーメイド生産の手法  
【洋裁型紙】前後身頃の肩の傾きは何故前身頃の方が傾いているのか  
電子追尾式天体写真撮影法  
日本ミツバチ巣箱の種類  
ドラフター(製図台)でソーイング  
日本ミツバチが逃亡  
カメさんの箱庭  
天体用デジタルカメラの構造と天体写真  
Javaで静止画像(Jpeg)を動画(Mov)に変換  
USBカメラをJAVAで制御  

他のサイト

3D-CAD
洋裁CAD

いいねなど

 RSS 

Author: Tomoyuki Ito

このサイトの文章・写真の無断転載を禁じます