#navi(Processing/3.ライブラリの利用): Not a child page like: Processing/3.ライブラリの利用/4-2.クラスの継承

4-2 クラスの継承---Fisicaの図形の描き方

次のスケッチを実行してみよう。

import fisica.*;

FWorld world;
FCircle ball1, ball2;

void setup(){
  size(600,300);
  Fisica.init(this);
  world = new FWorld();
  world.setEdges();
  world.setEdgesFriction( 0 );
  ball1=new FCircle(40);
  ball1.setDamping( 0 );
  ball1.setDensity( 2 );
  ball1.setFriction( 0.1 );
  ball1.setRestitution( 1 );
  ball1.setPosition( 50, 274.5 );
  ball1.setGrabbable( false );
  ball1.setFill( 128, 255, 128 );
  world.add( ball1 );

  ball2=new FCircle(40);
  ball2.setDamping( 0 );
  ball2.setDensity( 4 );
  ball2.setFriction( 0.1 );
  ball2.setRestitution( 1 );
  ball2.setPosition( 200, 274.5 );
  ball2.setGrabbable( false );
  ball2.setFill( 255, 128, 128 );
  world.bottom.setFill(128);
  world.top.setFill(128);
  world.left.setFill(192);
  world.right.setFill(192);
  world.bottom.setStroke(128);
  world.top.setStroke(128);
  world.left.setStroke(192);
  world.right.setStroke(192);
  world.add( ball2 );
}

void mouseClicked(){
  if( dist( mouseX, mouseY, ball1.getX(), ball1.getY()) < ball1.getSize() ){
    ball1.addImpulse( ball1.getMass()*200, 0, mouseX-ball1.getX(), mouseY-ball1.getY() );
  }
}

void draw(){
  background(0);
  world.step();
  world.draw();
}

これを実行すると、左側の球をマウスでクリックすると、クリックした点に力積が加えられる。

4-2-1.png

これだけでは、どこをクリックしてもあまり様子が変わらない。そこで、球のどこかに目印をつけて回転する様子を眺めてみよう。それには、自前のクラスMyBallを作成して、描き方だけを変えてみればよい。まず、クラスを定義する。

class MyBall extends FCircle{
  MyBall( float r ){
    super( r );
  }
  public void draw(PGraphics applet) {
    preDraw(applet);
    if (m_image != null ) {
      drawImage(applet);
    } else {
      applet.ellipse(0, 0, getSize(), getSize());
      applet.fill( 0 );
      applet.ellipse( getSize()/3, 0, 3, 3 );
    }
    postDraw(applet);
  }
}

1行目の

class MyBall extends FCircle

では、FCircleクラスを拡張して、MyBallクラスを定義することを宣言している。次の

MyBall( float r ){ super( r ); }

はnew MyBall( r )でインスタンスを作成するときに、拡張元であるFCircle( r )と同じ コンストラクタを利用することを書いている。

public void draw(PGraphics applet)

が球を描画する部分である。もともとのFCircleのdraw()は次の通りである。

public void draw(PGraphics applet) {
  preDraw(applet);
  if (m_image != null ) {
    drawImage(applet);
  } else {
    applet.ellipse(0, 0, getSize(), getSize());
  }
  postDraw(applet);
}

ここに

  applet.fill( 0 );
  applet.ellipse( getSize()/3, 0, 3, 3 );

として、getSize()で得られる直径の1/3のところに半径3の黒い点を追加して描く。 あとは、FCircleをMyBallに置き換えればよい。その結果を下記に示す。

import fisica.*;

FWorld world;
MyBall ball1, ball2;

class MyBall extends FCircle{
  MyBall( float r ){
    super( r );
  }
  public void draw(PGraphics applet) {
    preDraw(applet);

    if (m_image != null ) {
      drawImage(applet);
    } else {
      applet.ellipse(0, 0, getSize(), getSize());
      applet.fill( 0 );
      applet.ellipse( getSize()/3, 0, 3, 3 );
    }

    postDraw(applet);
  }
}


void setup(){
  size(600,300);
  Fisica.init(this);
  world = new FWorld();
  world.setEdges();
  world.setEdgesFriction( 0 );
  ball1=new MyBall(40);
  ball1.setDamping( 0 );
  ball1.setDensity( 2 );
  ball1.setFriction( 0.1 );
  ball1.setRestitution( 1 );
  ball1.setPosition( 50, 274.5 );
  ball1.setGrabbable( false );
  ball1.setFill( 128, 255, 128 );
  world.add( ball1 );

  ball2=new MyBall(40);
  ball2.setDamping( 0 );
  ball2.setDensity( 4 );
  ball2.setFriction( 0.1 );
  ball2.setRestitution( 1 );
  ball2.setPosition( 200, 274.5 );
  ball2.setGrabbable( false );
  ball2.setFill( 255, 128, 128 );
  world.bottom.setFill(128);
  world.top.setFill(128);
  world.left.setFill(192);
  world.right.setFill(192);
  world.bottom.setStroke(128);
  world.top.setStroke(128);
  world.left.setStroke(192);
  world.right.setStroke(192);
  world.add( ball2 );
}

void mouseClicked(){
  if( dist( mouseX, mouseY, ball1.getX(), ball1.getY()) < ball1.getSize() ){
    ball1.addImpulse( ball1.getMass()*200, 0, mouseX-ball1.getX(), mouseY-ball1.getY() );
  }
}


void draw(){
  background(0);
  world.step();
  world.draw();
}
4-2-2.png

調子に乗って、3次元的に描いてみる。上のプログラムとの違いは、

import fisica.*;

FWorld world;
MyBall ball1, ball2;
FBox bottom;

class MyBall extends FCircle{
  MyBall( float r ){
    super( r );
  }
  public void draw(PGraphics applet) {
    preDraw(applet);
    if (m_image != null ) {
      drawImage(applet);
    } else {
      applet.sphere( getSize()/2 );
    }
    postDraw(applet);
  }
}

void setup(){
  size(600,300,P3D);
  Fisica.init(this);
  world = new FWorld();
  world.setEdges();
  world.setEdgesFriction( 0 );
  ball1=new MyBall(60);
  ball1.setDamping( 0 );
  ball1.setDensity( 2 );
  ball1.setFriction( 0.1 );
  ball1.setRestitution( 1 );
  ball1.setPosition( 50, 264.5 );
  ball1.setGrabbable( false );
  ball1.setFill( 128, 255, 128 );
  ball1.setNoStroke();
  world.add( ball1 );

  ball2=new MyBall(60);
  ball2.setDamping( 0 );
  ball2.setDensity( 4 );
  ball2.setFriction( 0.1 );
  ball2.setRestitution( 1 );
  ball2.setPosition( 200, 264.5 );
  ball2.setGrabbable( false );
  ball2.setFill( 255, 128, 128 );
  ball2.setNoStroke();
  world.add( ball2 );
  world.bottom.setNoFill();
  world.top.setNoFill();
  world.left.setNoFill();
  world.right.setNoFill();
  world.bottom.setNoStroke();
  world.top.setNoStroke();
  world.left.setNoStroke();
  world.right.setNoStroke();
  println( world.bottom.getY() );
}

void drawEdges(){
  pushMatrix();
  translate( world.bottom.getX(), world.bottom.getY(), 0 );
  rotateX(radians(90));
  fill( 128 );
  rect( -500, -500, 1000, 1000 );
  popMatrix();
  pushMatrix();
  translate( world.left.getX(), world.left.getY(), 0 );
  rotateY(radians(90));
  fill( 192 );
  rect( -500, -500, 1000, 1000 );
  popMatrix();
  pushMatrix();
  translate( world.right.getX(), world.right.getY(), 0 );
  rotateY(radians(90));
  fill( 192 );
  rect( -500, -500, 1000, 1000 );
  popMatrix();
}  

void mouseClicked(){
    ball1.addImpulse( ball1.getMass()*200, 0 );
}


void draw(){
  background(0);
  lights();
  drawEdges();
  translate( 0, 0, -100 );
  world.step();
  world.draw();
}
4-2-3.png

トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS