ともさんのHP >プロブラミング >JavaFX >平坦なTriangleMesh作成Class

JavaFX TriangleMeshを生成するClass

平面で四角形のJavaFX TriangleMeshを生成するサンプルプログラムの紹介です。
アニメーションのしかたを紹介する他のページで使っています。
このページではClassの構造を紹介します。
TriangleMeshの作り方はこちらを参照ください。

広告

こんな3Dオブジェクトができます。
フラットなJavaFX TriangleMesh


応用でこんな形にも変形できます。
壺型のJavaFX TriangleMesh


MeshViewを作成するClass、FlatMesh

コンストラクタ FlatMesh(double px,double py, int x,int y,double s) で、X方向にpx間隔でx-1分割、Y方向にpy間隔でy-1分割、z座標0の四角で平坦なTriangleMeshを定義します。 このあと、getTriangleMesh()で、生成されたTriangleMeshを受け取ることができます。
アニメーションをするときには、TriangleMeshを構成する点pを取り出して座標を変えます。

TriangleMesh作成の手順

まず点と三角形のClassを用意します。
Point3CtはPoint3Dを拡張したもので、点番号を追加しています。

package tomojavalib.fx;

import javafx.geometry.Point3D;

public class Point3Dt extends Point3D {
public int no =0;

 public Point3Dt(double x, double y, double z,int i) {
  super(x, y, z);
  no = I;
 }
}

Triangleは三角形を構成する3つのPoint3Dtを格納します。

package tomojavalib.fx;

public class Triangle {
public Point3Dt[] p = new Point3Dt[3];
public Triangle( Point3Dt p1 , Point3Dt p2 , Point3Dt p3 ){
 p[0]=p1; p[1]=p2;p[2]=p3;
}
}

点を格子状に並べて作ります。3角形は、3つの点を定義することで配置します。
点は x * y 個
三角形は( x-1 )*( y-1 ) * 2 個作り、下の図のように並べます。

JavaFX TriangleMeshを構成する点

三角形
JavaFX TriangleMeshを構成する三角形


三角形に点を割り当てるには、下の図のように半時計まわりに3点を割り当てます。反時計回りだと、三角形に貼りつけられる面のの表が正面側になります。
図では三角形番号40と81を構成する番号を赤字で示しています。
3角形の点の割り当て


また、3角点は、構成点pのシャローコピー(Shallow Copy)で作っておきます。こうすると、構成点を変えるだけで三角形の3点も変更することができます。

n =0;
for(int ii=0;ii<y-1;ii++){
 for(int i=0;i<x-1;i++){
  int p1 = x*ii+I;
  int p3 = p1+1;
  int p2 = x*(ii+1)+I;  
  t[n] = new Triangle( p[p1] , p[p2] , p[p3] );
  n++;
  p1 = x*ii+i+1;
  p2 = x*(ii+1)+I;
  p3 = p2+1;  
  t[n] = new Triangle( p[p1] , p[p2] , p[p3] );
  n++;
 }
}

TriangleMesh構成データの作成

TriangleMeshを作るには、構成点の3次元座標を入れるPoints、テクスチャ貼り付けの2次元座標を入れるTexCoords、三角形を構成する点番号を入れるFacesの三つが必要です。
Pointは3次元点pの座標をそのまま入れます。
TexCoordsにはpのz座標を除いたものに、コンストラクタで入力したスケールを掛けたものを入れます。
Facesには、Point3Dtの番号をしめすnoを入れてゆきます。


平面で四角形のTriangleMeshを生成するサンプルプログラム

出来たコードが以下です。

package tomojavalib.fx;

import javafx.scene.shape.TriangleMesh;

/**平面、四角形のTriangleMeshを作成するclass*/
public class FlatMesh {
public Triangle[] t = null;
public Point3Dt[] p = null;
private double scale = 1.;

/**
 * 新規メッシュの作成
 */
public FlatMesh(double px,double py, int x,int y,double s){
scale =s;

//点と3角形の準備
 int nos = (int)( x * y );
 p = new Point3Dt[ nos ];
 nos =(int)( x-1 )*( y-1 ) * 2;
 t = new Triangle[ nos ];

//点を作成
int n =0;
 for(int ii=0;ii<y;ii++){
 for(int i=0;i<x;i++){
  double ax =  px*i ;
  double ay =  py*ii ;
  p[n] = new Point3Dt(  ax , ay , 0. , n );
  n++;
 }
}

//三角形を生成
n =0;
for(int ii=0;ii<y-1;ii++){
 for(int i=0;i<x-1;i++){
  int p1 = x*ii+I;
  int p3 = p1+1;
  int p2 = x*(ii+1)+I;  
  t[n] = new Triangle( p[p1] , p[p2] , p[p3] );
  n++;
  p1 = x*ii+i+1;
  p2 = x*(ii+1)+I;
  p3 = p2+1;  
  t[n] = new Triangle( p[p1] , p[p2] , p[p3] );
  n++;
 }
}
return;
}

/**3角形の構成情報を返す*/
public int[] getFaces(){
int[] faces = new int[ t.length *3*2 ];
int ii=0;
 for(int i=0;i<t.length;i++){
  faces[ii] = t[i].p[0].no;ii++;
  faces[ii] = t[i].p[0].no;ii++;
  faces[ii] = t[i].p[1].no;ii++;
  faces[ii] = t[i].p[1].no;ii++;
  faces[ii] = t[i].p[2].no;ii++;
  faces[ii] = t[i].p[2].no;ii++;
 }
return faces;
}

/**テクスチャ用の座標を返す*/
public float[] getTexCoords(){
 float[] texCoords = new float[ p.length*2 ];
 int i=0;
 for(int ii=0;ii<p.length;ii++){
  texCoords[i] = (float)( p[ii].getX() * scale );i++;
  texCoords[i] = (float)( p[ii].getY() * scale );i++;
 }
 return texCoords;
}

/**構成する3次元点を返す*/
public float[] getPoints(){
 float[] points = new float[ p.length*3 ];
 int pi=0;
  for(int ii=0;ii<p.length;ii++){
   points[pi] =(float)this.p[ii].getX();  pi++;
   points[pi] =(float)this.p[ii].getY();  pi++;
   points[pi] =(float)this.p[ii].getZ();  pi++;
  }
return points;
}

/**TriangleMeshを返す*/
public TriangleMesh getTriangleMesh(){
 TriangleMesh mesh = new TriangleMesh();
 mesh.getPoints().addAll( this.getPoints() );
 mesh.getTexCoords().addAll( this.getTexCoords() );
 mesh.getFaces().addAll( this.getFaces() );
return mesh;
}

}

広告


メッシュを表示するためのサンプルプログラム

下は生成したメッシュを表示するコードです。
フラットなJavaFX TriangleMesh

package tomojavalib.fx;

import javafx.application.Application;
import javafx.geometry.*;
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.CullFace;
import javafx.scene.shape.DrawMode;
import javafx.scene.shape.MeshView;
import javafx.scene.transform.*;
import javafx.stage.Stage;

/**単純なJavaFX楽天 プログラム
 *フラットメッシュを作成して表示
 * */
public class App18 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();
 //メッシュを置く
 FlatMesh fm = new FlatMesh( 5 , 5 , 20 , 20 , .01 );
 MeshView meshView  = new MeshView();
 meshView.setMesh( fm.getTriangleMesh() );
 meshView.setDrawMode( DrawMode.FILL);
 PhongMaterial material = new PhongMaterial();
 Image img = new Image("file:d:/work/java/2.png");
 material.setDiffuseMap( img );
 meshView.setMaterial(material);
 meshView.setCullFace(CullFace.NONE);
 group.getChildren().add( meshView );
 // カメラを置く
 PerspectiveCamera camera = new PerspectiveCamera( true );
 //方向と位置
 Translate cameratranslate = new Translate(50,50,-550);
 Rotate camerarotateX = new Rotate( 30 , new Point3D( 1 , 0 , 0 ) );
 Rotate camerarotateY = new Rotate( 30 , new Point3D( 0 , 1 , 0 ) );
 camera.getTransforms().add( camerarotateX );
 camera.getTransforms().add( camerarotateY );
 camera.getTransforms().add( cameratranslate ); 
 //可視範囲
 camera.setFarClip( 1000. );
 //視界の角度
 camera.setFieldOfView( 30. );
 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 );

return s3d;
}
}


応用


壺型のJavaFX getTriangleMesh

点の座標を定義するさいに三角関数を使うなどすれば、円筒や壺型のメッシュを作ることができます。
この場合、テクスチャの座標がおかしくなってしまうので、別途作成する必要があります。

  double ax = Math.sin( (i/(double)x)*2.*Math.PI )*Math.cos( (ii/(double)y)*.5*Math.PI )*50.;
  double az = Math.cos( (i/(double)x)*2.*Math.PI )*Math.cos( (ii/(double)y)*.5*Math.PI )*50.;
  double ay = ii*5;
  p[n] = new Point3Dt(  ax , ay , az , n );


最終更新日: 2017-03-10 17:52:28

ともさんのHP >プロブラミング >JavaFX >平坦なTriangleMesh作成Class

広告
新着ページ

渋柿で柿渋作り  
新旧文化式とドレメ式原型製図を比較  
水棚の作り方  
DXFファイルの違い  
デジタル顕微カメラ  
萩の栽培、手入れ、増やしかた  
セミの飼いかた  
ダンゴムシの飼い方  
玉縁ボタンホールの縫い方  
柿渋  
ミシンでボタンを付ける  

他のサイト

3D-CAD
洋裁CAD

いいねなど

 RSS 

Author: Tomoyuki Ito

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