2009年5月26日火曜日

Ubuntu Serverでネットワークに接続できない

このエントリーをはてなブックマークに追加
Ubuntu Server9.04をVM Ware上にインストールしましたが,初期状態でネットワークに接続できません(IPが正しく割り振られません)でした.
少し詰まったのでメモ

ネットワークカードを正常に認識していなかったようです.

1.ネットワークデバイス名を調べる
# lshw -C network

logical name をメモ
私の環境ではeth0でした.

2.ネットワークデバイスの設定
# vi /etc/network/interfaces
---------------------------
auto lo
iface lo inet loopback
# 以下を追記
auto eth0
iface eth0 inet dhcp
---------------------------


3.ネットワークの再起動
# /etc/init.d/networking restart


以上により,正常にIPが割り振られネットワークに接続できます.

2009年5月7日木曜日

JBox2Dのプログラムサンプル

このエントリーをはてなブックマークに追加
2D物理シュミレーションエンジンBox2DのJavaバージョンであるJBox2Dを使用してみました.
JBox2D:http://www.jbox2d.org/


以下のプログラムは,ある閉じた空間(2D)内に複数のボールを用意し,物理演算を行ってボールが跳ねる様子を見ることができます.
また,自由に新しいボールや壁を追加することができます.


[PhysicalWorld.java]

import org.jbox2d.collision.AABB;
import org.jbox2d.collision.CircleDef;
import org.jbox2d.collision.PolygonDef;
import org.jbox2d.collision.Shape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.World;
import org.jbox2d.dynamics.joints.MouseJoint;
import org.jbox2d.dynamics.joints.MouseJointDef;
import org.jbox2d.collision.*;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;

import java.util.*;

public class PhysicalWorld extends JFrame {
public static void main(String[] args) {
new PhysicalWorld();
}

public PhysicalWorld() {
// タイトルを設定
setTitle("MyFrame");
// 閉じるボタンを押した際,プログラムを終了
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 起動時のロケーション設定
// setLocation(0, 0);

// メインパネルを作成してフレームに追加
MainPanel panel = new MainPanel();
Container contentPane = getContentPane();
contentPane.add(panel);
setVisible(true);
// パネルサイズに合わせてフレームサイズを自動設定
pack();
}
}

class MainPanel extends JPanel implements Runnable {
// パネルサイズ
private static int width = 600;
private static int height = 400;
// 1m = 10px
private static final int WORLD_SCALE = 10;
private World mWorld;

// 壁格納用リスト
private java.util.List groundBodyList = new ArrayList();
// ボール格納用リスト
private java.util.List ballBodyList = new ArrayList();

// マウスジョイント
private MouseJointDef mouseJointDef;
private MouseJoint mouseJoint;

// アニメーション用スレッド
private Thread thread;
Body ballBody;

public MainPanel() {
initMainPanel();
initWorld();
initGround();
initBall();
// スレッドを起動
thread = new Thread(this);
thread.start();
}

private void initMainPanel() {
// パネルの推奨サイズを設定
// pack()するときに必要
setPreferredSize(new Dimension(width, height));
setBackground(Color.BLACK);
// マウスリスナを登録
this.addMouseListener(new MyListener());
this.addMouseMotionListener(new MyListener());
}

private void initWorld() {
Vec2 minV = new Vec2(-100,-100);
Vec2 maxV = new Vec2(100,100);
AABB aabb = new AABB(minV,maxV);
mWorld = new World(aabb, new Vec2(0.0f,9.8f),true);
}

private void initGround() {
// 上壁
createGroundBody(0.0f, 0.0f, (width * 0.9f) / WORLD_SCALE, 0.0f);
// 下壁
createGroundBody(0.0f, (height * 0.9f) / WORLD_SCALE, (width * 0.9f) / WORLD_SCALE, (height * 0.9f) / WORLD_SCALE);
// 左壁
createGroundBody(0.0f, 0.0f, 0.0f, (height * 0.9f) / WORLD_SCALE);
// 右壁
createGroundBody((width * 0.9f) / WORLD_SCALE, 0.0f, (width * 0.9f) / WORLD_SCALE, (height * 0.9f) / WORLD_SCALE);
}

private void initBall() {
// ボールの作成
for(int i = 15; i < 30; i++){
createBallBody((float)i, 10.0f);
}

// ジョイント用ボールの作成
BodyDef ballBodyDef = new BodyDef();
ballBodyDef.position.set(15.0f, 5.0f);
CircleDef ballShapeDef = new CircleDef();
ballShapeDef.radius = 1.0f;
ballShapeDef.density = 1.0f;
ballShapeDef.restitution = 0.7f;

ballBody = mWorld.createBody(ballBodyDef);
ballBody.createShape(ballShapeDef);
ballBody.setMassFromShapes();
ballBodyList.add(ballBody);

mouseJointDef = new MouseJointDef();
mouseJointDef.body1 = mWorld.getGroundBody();
mouseJointDef.body2 = ballBody;
mouseJointDef.target =  ballBody.getWorldCenter();
mouseJointDef.maxForce = 1000;
}

private void createGroundBody(float sx, float sy, float ex, float ey){
BodyDef groundBodyDef = new BodyDef();
groundBodyDef.position.set((sx + ex)/2.0f, (sy + ey)/2.0f);
PolygonDef groundShapeDef = new PolygonDef();
int angle = (int)(Math.atan((double)(ey - sy) / (double)(ex - sx)) * 180 / Math.PI);
float dis = (float)Math.sqrt(Math.pow((sx-ex), 2) + Math.pow((sy-ey), 2)) / 2.0f;
groundShapeDef.setAsBox(dis, 0.1f, new Vec2(0,0),(float)(Math.PI * angle / 180.0));
Body groundBody = mWorld.createBody(groundBodyDef);
groundBody.createShape(groundShapeDef);
groundBodyList.add(groundBody);
}

private void createBallBody(float x, float y){
BodyDef ballBodyDef = new BodyDef();
ballBodyDef.position.set(x, y);
CircleDef ballShapeDef = new CircleDef();
ballShapeDef.radius = 1.0f;
ballShapeDef.density = 1.0f;
ballShapeDef.restitution = 0.7f;
Body ballBody = mWorld.createBody(ballBodyDef);
ballBody.createShape(ballShapeDef);
ballBody.setMassFromShapes();
ballBodyList.add(ballBody);
}

public void paintComponent(Graphics g) {
super.paintComponent(g);

g.setColor(Color.GREEN);

for(Body groundBody : groundBodyList){
Shape shape = groundBody.getShapeList();
Vec2[] vPts = ((PolygonShape)shape).getVertices();

int minX = (int)Math.min(Math.min(vPts[0].x, vPts[1].x), Math.min(vPts[2].x, vPts[3].x));
int minY = (int)Math.min(Math.min(vPts[0].y, vPts[1].y), Math.min(vPts[2].y, vPts[3].y));
int maxX = (int)Math.min(Math.max(vPts[0].x, vPts[1].x), Math.max(vPts[2].x, vPts[3].x));
int maxY = (int)Math.min(Math.max(vPts[0].y, vPts[1].y), Math.max(vPts[2].y, vPts[3].y));

minX = (int)(groundBody.getWorldCenter().x + minX) * WORLD_SCALE;
minY = (int)(groundBody.getWorldCenter().y + minY) * WORLD_SCALE;
maxX = (int)(groundBody.getWorldCenter().x + maxX) * WORLD_SCALE;
maxY = (int)(groundBody.getWorldCenter().y + maxY) * WORLD_SCALE;

if(vPts[0].y <= vPts[1].y){
g.drawLine(minX, minY, maxX, maxY);
} else {
g.drawLine(minX, maxY, maxX, minY);
}
}

g.setColor(Color.RED);
int r = 2;
Vec2 pos;

for(Body ballBody : ballBodyList){
pos = ballBody.getWorldCenter();
g.fillOval((int)((pos.x-r/2) * WORLD_SCALE), (int)((pos.y-r/2) * WORLD_SCALE), r*WORLD_SCALE, r*WORLD_SCALE);
}
}

// メインループ
public void run() {
// プログラムが終了するまでフレーム処理を繰り返す
while (true) {
mWorld.step(1/20f, 8);

// ボールを再描画
repaint();

// 20ミリ秒だけ休止
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public class MyListener extends MouseAdapter {
Point startP,endP;

// ボタンプレス時
public void mousePressed(java.awt.event.MouseEvent e){
if((e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0){         // 左クリック
// ジョイントの作成
mouseJoint = (MouseJoint)mWorld.createJoint(mouseJointDef);
mouseJoint.m_localAnchor = ballBody.getLocalCenter();
} else if((e.getModifiers() & MouseEvent.BUTTON3_MASK) != 0){   // 右クリック
// クリックポイントの作成
startP = e.getPoint();
}
}   

// ボタンリリース時
public void mouseReleased(java.awt.event.MouseEvent e){
if((e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0){
// ジョイントの削除
mWorld.destroyJoint(mouseJoint);
mouseJoint = null;
} else if((e.getModifiers() & MouseEvent.BUTTON3_MASK) != 0){
// リリース場所の格納
endP = e.getPoint();
if(Math.abs(startP.x - endP.x) < 3 && Math.abs(startP.y - endP.y) < 3){   // プレス時とリリース時にあまり差が無い場合
// 新しいボールを作成
createBallBody(startP.x / WORLD_SCALE, startP.y / WORLD_SCALE);
} else {
// プレス場所からリリース場所まで壁を作成する
createGroundBody(startP.x / WORLD_SCALE, startP.y / WORLD_SCALE, endP.x / WORLD_SCALE, endP.y / WORLD_SCALE);
}
}
}

// マウスドラッグ時
public void mouseDragged(java.awt.event.MouseEvent e){
if((e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0){
if(mouseJoint != null){
// ボールの移動
int x = e.getPoint().x / WORLD_SCALE;
int y = e.getPoint().y / WORLD_SCALE;
mouseJoint.setTarget(new Vec2(x, y));
}
}
}
}
}