Bullet Physics Libraryを使ってみた

新入生のGL講習会を担当することになったので,面白いことが出来ないかな〜と思ってBullet Physics Libraryを使ってみた.

ライブラリとサンプルはここからDLする.

Macは残念ながら,cmakeでXcodeプロジェクトを作らないとダメみたい.
cmakeのコマンドは cmake . -G Xcode を実行すればOK

僕は一発で通りました(実行環境:OS X 10.7.5, cmake 2.8.9).

f:id:sngymn:20130411124602j:plain

上記の赤枠の部分が生成されたもの.

その他の詳細はDLしたtgzファイルに付属しているBullet_User_Manual.pdfを参照ってことで...

あとはBULLET_PHYSICS.xcodeprojを開いてビルドすれば開発環境の完成? サンプルも豊富で取り敢えず遊べます.

お気に入りはスライムみたいなシミュレーション!! 何これ,キモいw

f:id:sngymn:20130411124609p:plain

プログラミング初心者でも楽しめるものを作ろう...無理な気がしてきたw

FizzBuzz問題 ~Pyton2.7系~

最近、HACKERRANKというプログラミングのクイズを提供してくれるものにハマってる。各カテゴリー別に分かれて、Max Socreを叩き出しランキングを上げていく。そのカテゴリーの中にCode Golfというものがあって、いかに短いコードを記述するかを競うものがある。

今回は、誰もが?やったことある"FizzBuzz問題"を解く。

普通に記述すると...
for i in range(1,101):
    if i%15 == 0:
        print 'FizzBuzz'
    elif i%5 == 0:
        print 'Buzz'
    elif i%3 == 0:
        print 'Fizz'
    else:
        print i

スペースやタブを使うとバイト数が増えるので、(若干)見にくいけどワンライナーで行く。

 

1回目のSubmitでScore:12.5 
for i in range(1,101):print (""if(i%3)else"Fizz")+(""if(i%5)else"Buzz")or i

if~elseの文字数が邪魔だ。

ちなみに、Socre=(200 - number of characters)/10で計算される。

 

2回目のSubmitでScore:14
  for i in range(1,101):print"Fizz"*(i%3<1)+"Buzz"*(i%5<1)or i

if~else文を削除してみた。今度はrangeを(100)にして"1,"を削除する。

 

3回目のSubmitでScore14.3
 for i in range(100):print i%3/2*'Fizz'+i%5/4*'Buzz'or i+1

もう無理なんじゃ...でも、リーダーボードでは14.4がPython2.xの最大Scoreになってる。どこを1文字減らせば良いのか...分からん。

はてなブログ(無料版)でキーワードリンクを回避する

無料版でsyntaxHighlighterを使うと...コードの中までキーワードリンクしてくる(´・ω・`)

Hello Worldプログラムで説明すると

通常

#include <iostream>

int main()
{
    std::cout << "Hello World!\n";
	return 0;
}

残念なことになる

キーワードリンク回避処理後

#include <iostream>

int main()
{
    std::cout << "Hello World!\n";
    return 0;
}

キーワードリンクが回避出来ている

解決方法は<pre class="brush:cpp" data-unlink=""></pre>とすれば良いだけ!!

SiriProxyを使ってみた

参考サイト (というかそのまま)
SiriProxyのプラグインとしてSiriで家電を操作するSiriProxy-iRemocon

SiriProxyはSiriのProxyサーバーです。要は、Siriで話した内容の解析結果をPCに飛ばせるよってこと(細かいことは気にしない...) 詳しいことは、参考サイトを参照w

Rubyを入れる
rvm install 1.9.3
gem install bundler
DNSの設定

confファイルを雛形から作成して、address情報を追記する

brew install dnsmasq
cp /usr/local/opt/dnsmasq/dnsmasq.conf.example /usr/local/etc/dnsmasq.conf
vi /usr/local/etc/dnsmasq.conf
# Add domains which you want to force to an IP address here.
# The example below send any host in double-click.net to a local
# web-server.
#address=/double-click.net/127.0.0.1
# 192.168.1.29はSiriProxyが可動するマシンのアドレス
address=/guzzoni.apple.com/192.168.1.29

アドレスはifconfigとかして調べる

ifconfig | grep inet 

保存してから下記のコマンドで稼働する

sudo /usr/local/sbin/dnsmasq

稼働させたら、{iPhone, iPad} のDNSアドレスを192.168.1.29で更新する

SiriProxyのSetup

ライブラリやプロファイルを作成する

git clone https://github.com/plamoni/SiriProxy.git
cd SiriProxy
mkdir ~/.siriproxy
cp ./config.example.yml ~/.siriproxy/config.yml
gem install /Users/sngymn/SiriProxy/pkg/siriproxy-0.4.4.gem
rake install
siriproxy gencerts

gemcertsで~/.siriproxy/ca.pemというプロファイルが生成される
これをメールか何かで {iPhone, iPad} に送りつけてインストールする

SiriProxyの起動
bundle install
siriproxy update
rvmsudo siriproxy server

sudo siriproxy serverでも起動できる

あとは、Siriに向かって喋るだけ!!

[Info - Plugin Manager] Plugins loaded: [#<SiriProxy::Plugin::Example:0x007fca5a370d58 @manager=#<SiriProxy::PluginManager:0x007fca5a371320 @plugins=[...]>>]
[Info - iPhone] Received Object: LoadAssistant
[Info - iPhone] Received Object: SetRestrictions
[Info - iPhone] Received Object: ClearContext
[Info - iPhone] Received Object: StartSpeechRequest
[Info - iPhone] Received Object: SetRequestOrigin
[Info - User Location] lat: 35.65755939007164, long: 139.5430340842567
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SetBackgroundContext
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - Guzzoni] Received Object: AssistantCreated
[Info - Guzzoni] Received Object: AssistantLoaded
[Info - Guzzoni] Received Object: SetConnectionHeader
[Info - iPhone] Received Object: FinishSpeech
[Info - Guzzoni] Received Object: AddViews
[Info - iPhone] Received Object: SetAssistantData
[Info - Guzzoni] Received Object: CommandFailed
[Info - iPhone] Received Object: Chunk
[Info - iPhone] Received Object: Finished
[Info - iPhone] Received Object: StartSpeechRequest
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - Guzzoni] Received Object: ChunkAccepted
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: FinishSpeech
[Info - Guzzoni] Received Object: SpeechRecognized
[Info - Plugin Manager] Processing 'テスト '
[Info - Plugin Manager] Processing plugin #<SiriProxy::Plugin::Example:0x007fca5a370d58>

何も処理をしないと、こんな感じでレスポンスが飛んできます
あれ...User Location?? 現在地が抜かれてるw さすが...

openFrameworksでマルチタッチしてみた (Mac only)

Mac純正のマルチタッチフレームワークであるMultitouchSupport.frameworkを使ってマルチタッチをしてみる

参考サイトは死んでるので、覚えてる範囲で...

 

必要なもの

  1. openFrameworks本体
  2. ofxVectorMath (Addon)
  3. MultitouchSupport.framework (/System/Library/PrivateFrameworks/にある)
  4. ofxOsc (任意)

手順

  1. ofxVectorMath、MultitouchSupport.frameworkとofxOscをXcodeのプロジェクトに入れる...ドラッグするだけ
    こんな感じになる

    f:id:sngymn:20130303015719p:plain

  2. testApp.cppをtestApp.mmに変更する
    一応、ファイルタイプがObjective-C++ Sourceになってるか確認
  3. コードを書く
#pragma once

#include "ofMain.h"
#include "ofxOsc.h"

#define TUIOPORT 3333

class testApp : public ofBaseApp{
public:
    void setup();
	void update();
	void draw();
		
	void keyPressed(int key);
	void keyReleased(int key);
	void mouseMoved(int x, int y);
	void mouseDragged(int x, int y, int button);
	void mousePressed(int x, int y, int button);
	void mouseReleased(int x, int y, int button);
	void windowResized(int w, int h);
			
    int width, height;
	ofxOscSender send;
};

#include "testApp.h"
#include "ofVectorMath.h"

extern "C" {
    typedef struct { float x,y; } mtPoint;
	typedef struct { mtPoint pos,vel; } mtReadout;
	typedef struct {
		int frame;
		double timestamp;
		int identifier, state, foo3, foo4;
		mtReadout normalized;
		float size;
		int zero1;
		float angle, majorAxis, minorAxis;
		mtReadout mm;
		int zero2[2];
		float unk2;
	}
	Finger;
	
	typedef void *MTDeviceRef;
	typedef int (*MTContactCallbackFunction)(int,Finger*,int,double,int);
	
	CFMutableArrayRef MTDeviceCreateList(void);
	void MTRegisterContactFrameCallback(MTDeviceRef, MTContactCallbackFunction);
	void MTDeviceStart(MTDeviceRef, int);
}


class TouchPoint {
public:
	ofVec2f pos;
	ofVec2f vel;
	float size;
	int id;
	bool enable;
	float phase;
	float freq, amp;
	float trem_phase;
	int stat;
};

vector<TouchPoint> touchPoints;

int mtCallback(int device, Finger *data, int nFingers, double timestamp, int frame) {
	for (int i = 0; i < touchPoints.size(); i  ++) {
		touchPoints[i].enable = false;
	}
	for (int i=0; i<nFingers; i++) {
		Finger *f = &data[i];
		
		/*
		 printf("Frame %7d: Angle %6.2f, ellipse %6.3f x%6.3f; "
		 "position (%6.3f,%6.3f) vel (%6.3f,%6.3f) "
		 "ID %d, state %d [%d %d?] size %6.3f, %6.3f?n",
		 f->frame,
		 f->angle * 90 / atan2(1,0),
		 f->majorAxis,
		 f->minorAxis,
		 f->normalized.pos.x,
		 f->normalized.pos.y,
		 f->normalized.vel.x,
		 f->normalized.vel.y,
		 f->identifier, f->state, f->foo3, f->foo4,
		 f->size, f->unk2);
		 */
		
		TouchPoint &t = touchPoints[f->identifier];
		t.pos.x = f->normalized.pos.x;
		t.pos.y = 1 - f->normalized.pos.y;
		t.size = f->size;
		t.enable = true;
		t.id = f->identifier;
		t.vel.x = f->normalized.vel.x;
		t.vel.y = f->normalized.vel.y;
		t.stat = f->foo3;
	}
	return 0;
}


void testApp::setup() {
	touchPoints.resize(20);
	
	NSMutableArray* deviceList = (NSMutableArray*)MTDeviceCreateList();
	for(int i = 0; i < [deviceList count]; i ++) { 
		MTRegisterContactFrameCallback([deviceList objectAtIndex:i], mtCallback);
		MTDeviceStart([deviceList objectAtIndex:i], 0);
	}
	
	ofEnableSmoothing();
	ofEnableAlphaBlending();
	ofSetVerticalSync(true);
	ofSetFrameRate(60);
	
	ofHideCursor();
	
	ofBackground(0, 0, 0);
	
	ofSetColor(255, 255, 255);
	ofNoFill();
	
	width = ofGetWidth();
	height = ofGetHeight();
	send.setup("127.0.0.1", TUIOPORT);
}


void testApp::update() {	
	
}

void testApp::draw() {
	for (int i = 0; i < touchPoints.size(); i++)
	{
		TouchPoint &t = touchPoints[i];
		
		if (t.enable == false) {

			continue;
		}
		
		float xx = t.pos.x * width;
		float yy = t.pos.y * height;
		ofCircle(xx, yy, t.size * 50);
		
		ofDrawBitmapString("x: " + ofToString(t.pos.x*width), xx-10, yy-15);
		ofDrawBitmapString("y: " + ofToString(t.pos.y*height), xx-10, yy);
		ofDrawBitmapString("ID :" + ofToString(t.id), xx-10, yy+15);
		ofDrawBitmapString("ID :" + ofToString(t.id), xx-10, yy+15);
		cout << t.stat << endl;
		
		ofxOscMessage m;
		m.setAddress("/tuio/2Dcur");
		m.addStringArg("set");
		m.addIntArg(t.id);
		m.addFloatArg(t.pos.x);
		m.addFloatArg(t.pos.y);
		m.addFloatArg(t.vel.x);
		m.addFloatArg(t.vel.y);
		m.addFloatArg(t.vel.x * t.vel.y);
		send.sendMessage(m);
	}
}

void testApp::keyPressed(int key) {
	if(key == 'f')
		ofToggleFullscreen();
	if (key == 'i') {
		width = ofGetWidth();
		height = ofGetHeight();
	}
}

void testApp::keyReleased(int key) {
}

void testApp::mouseMoved(int x, int y){
}

void testApp::mouseDragged(int x, int y, int button) {
}

void testApp::mousePressed(int x, int y, int button) {
}

void testApp::mouseReleased(int x, int y, int button) {
}

void testApp::windowResized(int w, int h) {
}

これを実行すればこんな感じになるはず...

f:id:sngymn:20130303020400p:plainメンバ変数をPrivateにしてないのは(ry

oFの仕様なのか、ofGetWidth()とかはofToggleFullscreen()を実行しても更新されないようです

SyntaxHighlighterを導入してみた

参考文献

はてなブログでSyntaxHighlighterでObjective-Cを表示

詳しいことは上記のサイトで...とりあえず、簡単にまとめる

 

  1. shCoreDefault.css(好きなのでOK)をはてなブログのデザインCSSに貼り付ける
  2. shCore.jsをHTMLサイドバーに追加
    コピペでは上手く動かない場合は、ホスティングを利用
  3. 必要なshBruchXxx.jsを2のHTMLサイドバーに追加
  4. 3の後に<script type="text/javascript">SyntaxHighlighter.all();</script>を追加
  5. はてなブログの設定からWYSIWYGモードする
  6. コードを記述!!
C++ (highlight:[4,6])
#include <iostream>
int main()
{
  std::cout << "Hello World!!" << std::endl;

  return 0;
}
Python (collapse:true)
print("Hello World!!")

Javascript (gutter:false)
document.write("Hello World!!");
Objective-C (title:[HelloWorld.m], first-line:[10])
#include <Foundation/NSObject.h>
#include 

@interface HelloWorld : NSObject
- (void) hello;
@end

@implementation HelloWorld

- (void) hello{
  printf("Hello World.\n");
}

@end

int main(int argc, char **argv){
  id obj = [HelloWorld alloc];
  [obj hello];
  
  return 0;
}
CSS
 BODY {
  background-image: url("img/xxx.jpg");
  background-repeat: repeat-y
}
Bash (toolbar:false)
sed -e 's/</\&lt;/g' -e 's/>/\&gt;/g'

出来た〜☆-(ノ゚Д゚)八(゚Д゚ )ノイエーイ

SyntaxHighlighterのまとめ

  1. SyntaxHighlighterのBrushはここからDLできる
  2. (当たり前だが...)環境依存文字には注意
  3. オプションが沢山ある
    ・first-line:[number] (Default:1)
    ・pad-line-numbers (Default:false)
    ・highlight:[number] (Default:null、複数行の場合は','で区切る)
    ・smart-tabs (Default:true)
    ・tab-size:[number] (Default:4)
    ・gutter (Default:true)
    ・toolbar (Default:true)
    ・quick-code (Default:true)
    ・collapse (Default:false)
    ・auto-links (Default:true)
    まだあるみたいだが、割愛...