2017年11月6日 星期一

JavaFX 3D - Cylinder

繼上一篇JavaFX 3D - Box,本篇將介紹Cylinder類別。

Cylinder類別用以建立圓柱體,其建構函式如下,分別由heightradius參數圓柱體的與半徑,此外divisions參數圓柱體的分割等分,以產生不同類型的立方柱體請參考後續範例

  public Cylinder()
  public Cylinder(double radius, double height) 
  public Cylinder(double radius, double height, int divisions) 

提供以下方法:
  • getHeight():取得圓柱體的高度
  • setHeight()設定圓柱體的高度。
  • getRadius():取得圓柱體的半徑。
  • setRadius()設定圓柱體的半徑。
  • getDivisions():取得圓柱體的分割等分
請參考以下範例分別示範以setCullFace()setDrawMode()方法不同的組合所產生的效果
// 建立Cylinder物件
Cylinder cylinder = new Cylinder(100, 100); 
// 以Wireframe方式呈現
cylinder.setDrawMode(DrawMode.LINE); 
// 不省略
cylinder.setCullFace(CullFace.NONE); 
// 平移Cylinder物件
cylinder.setLayoutX(150); 
cylinder.setLayoutY(150); 
// 旋轉Cylinder物件
cylinder.getTransforms().add(new Rotate(20,Rotate.X_AXIS));
cylinder.getTransforms().add(new Rotate(10,Rotate.Z_AXIS));
cylinder.getTransforms().add(new Rotate(30,Rotate.Y_AXIS)); 

Group root = new Group(); 
root.getChildren().add(cylinder);
...
【執行結果】
// 建立Cylinder物件
Cylinder cylinder = new Cylinder(100, 100); 
// 以Wireframe方式呈現
cylinder.setDrawMode(DrawMode.LINE); 
// 省略Back Face
cylinder.setCullFace(CullFace.BACK); 
...
【執行結果】
// 建立Cylinder物件
Cylinder cylinder = new Cylinder(100, 100); 
// 以Wireframe方式呈現
cylinder.setDrawMode(DrawMode.LINE); 
// 省略Front Face
cylinder.setCullFace(CullFace.FRONT); 
...
【執行結果】
// 建立Cylinder物件
Cylinder cylinder = new Cylinder(100, 100); 
// 以填滿方式呈現
cylinder.setDrawMode(DrawMode.FILL); 
// 省略Back Face
cylinder.setCullFace(CullFace.BACK); 
...
【執行結果】
// 建立Cylinder物件
Cylinder cylinder = new Cylinder(100, 100); 
// 以填滿方式呈現
cylinder.setDrawMode(DrawMode.FILL); 
// 省略Front Face
cylinder.setCullFace(CullFace.FRONT);
...
【執行結果】
以下範例示範setMaterial()方法設定貼圖
// 建立Cylinder物件
Cylinder cylinder = new Cylinder(100, 100); 

Image image = new Image(  
  getClass().getResourceAsStream("images/Javafx.png")); 

// 設定材質
PhongMaterial material = new PhongMaterial(); 
// 設定貼圖
material.setDiffuseMap(image);
...
【執行結果】
divisions參數用以圓柱體的分割等分,以下是以Cylinder建構函式圓柱體的切割為八角柱體 (Octagonal Prism)
// 建立Cylinder物件
Cylinder cylinder = new Cylinder(100, 100, 8); 

Image image = new Image(  
  getClass().getResourceAsStream("images/Javafx.png")); 

// 設定材質
PhongMaterial material = new PhongMaterial(); 
// 設定貼圖
material.setDiffuseMap(image);
...
【執行結果】
此外,可加入滑鼠事件,當滑鼠移動時 (Mouse Moved),藉由Rotate類別旋轉物件
scene.setOnMouseMoved((MouseEvent e) -> {
  newX = e.getX(); 
  if (Math.abs(newX - oldX) > 5) { 
    cylinder.getTransforms().add(
      new Rotate(newX - oldX, Rotate.X_AXIS)); 
    oldX = newX; 
  } 

  newY = e.getY(); 
  if (Math.abs(newY - oldY) > 5) { 
    cylinder.getTransforms().add(
      new Rotate(newY - oldY, Rotate.Y_AXIS)); 
    oldY = newY; 
  } 
});
...
亦可試著以Timeline類別設定時間軸,以產生動畫效果
final Timeline timeline = new Timeline(
  new KeyFrame(Duration.millis(50), new EventHandler() { 

  double deltaX = 20.0, deltaY = 30.0, deltaZ = 10.0; 

  @Override public void handle(final ActionEvent e) { 
    cylinder.getTransforms().add(new Rotate(deltaX, Rotate.X_AXIS)); 
    deltaX += 10; 
    cylinder.getTransforms().add(new Rotate(deltaY, Rotate.Y_AXIS)); 
    deltaY += 10; 
    cylinder.getTransforms().add(new Rotate(deltaZ, Rotate.Z_AXIS)); 
    deltaZ += 10; 
  } 
})); 

timeline.setCycleCount(Timeline.INDEFINITE); 
timeline.play();
...
【參考資料】

[1] 黃嘉輝,深入研究JavaFX 2。
[2] 黃嘉輝,JavaFX遊戲程式設計。
[3] Java Official Web Site:http://www.oracle.com/technetwork/java/index.html
[4] JavaFX:http://www.oracle.com/technetwork/java/javafx
[5] JavaFX 8.0 API Specification.
[6] Java Platform, Standard Edition 8 API Specification.
[7] JDK 8 Certified System Configurations.
[8] H. M. Cundy, A. P. Rollett, Mathematical Models, Tarquin Publications, 1981.
[9] G. Sellers, R. S. Wright, N. Haemel, OpenGL SuperBible: Comprehensive Tutorial and Reference (6th Edition), Addison-Wesley Professional, 2013.

© Chia-Hui Huang

沒有留言:

張貼留言