verticalline  Lsystem introduction
undeline

http://ja.wikipedia.org/wiki/L-system

G = {V, S, ω, P},

参考ページ

http://local.wasp.uwa.edu.au/~pbourke/fractals/lsys/

http://local.wasp.uwa.edu.au/~pbourke/fractals/

http://local.wasp.uwa.edu.au/~pbourke/fractals/lsys_leaf/

V  A          変数
S  無し         定数
ω  A             最初の文字列の状態
P  ( A ->AB )( B ->BA ) 「A」の文字にあたる部分を「AB」, 「B」の文字にあたる部分を「A」に書き換える

 

V  F           変数
S  [ ] - +        定数
ω  F             最初の文字列の状態
P  ( F -> F[+FF][-F]F ) 「F」の文字にあたる部分を「F[+FF][-F]F」に書き換える

基本的に「文字(コード)を書き換える命令(コード)が文字(コード)の中に含まれているシステム」、と考えても良いかもしれない。

verticalline Lsystem コア部分
undeline

文字列 を書き換えるプログラムを組めばよいです。

blab_lsystem.zip このフレームからはじめてみてください。

文字列をL-Systemの考え方に従って書き換えていく機能を考える。
P  ( A ->AB )( B ->BA ) 「A」の文字にあたる部分を「AB」, 「B」の文字にあたる部分を「A」に書き換える

この場合の P には2種類の動作があります。

「A」の文字にあたる部分を「AB」

「B」の文字にあたる部分を「BA」

std::string testApp::rule(std::string &acode, char rep, std::string rew);

という関数として実装してみましょう。

変更後の文字列を返す testApp::rule(変更前の文字列, 置き換える文字, 置き換えられる文字);

関連:

size_t 文字列 .find(探す文字、探し始める位置);

文字列の中から指定する文字の位置を返します。

size_t :

ほぼ int と同じ型を示すものですが、もっと大きな整数を扱えます。

 

verticalline Lsystem 生成されるコードの利用
undeline

SndObjと組み合わせる。

lsystemで生成・変化している文字列ひとつづつ読み、文字に応じてfrequencyを変化させる。

testApp.h 内

define MACOSX
#include <SndObj/AudioDefs.h>
//このあたりはSndObjのサンプルと一緒

int codeCount; //文字列をどこまで読んだか記録しておくための整数変数

testApp.cpp 内

void testApp::setup() {} 内

codeCount = 0 ; // 0からスタート

//このあたりはSndObjのサンプルと一緒
table1=new HarmTable(1024,1,SINE); //SIN
oscil=new Oscili(table1, 440.f, 10000.f);

output=new SndRTIO(2, SND_OUTPUT);

output->SetOutput(1, oscil);

sndthread.AddObj(oscil);
sndthread.AddObj(output, SNDIO_OUT);
sndthread.ProcOn();
//このあたりはSndObjのサンプルと一緒

void testApp::update() {} 内

if(lsys_code.size())>codeCount)
{

codeCount++;

}else
{

codeCount=0;

}// 文字列のカウントを繰り返す

//文字列の中のカウントに当たる文字によって音を変化

switch(lsys_code[codeCount])
{

case 'A' :

osil-LSetFreq(440.0);
break;

case 'B' :

osil-LSetFreq(1800.0);
break;

}

void testApp::draw() {} 内

glClearColor(0.1,0,0,0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
font.drawString( lsys_code ,0 ,98); // 文字列表示

void testApp::exit(){

delete table1;
delete oscil;
delete output;

}

verticallineLsystem 生成されるコードの利用
undeline

描画する。

描画クラス LSysDraw : 以下の座標変換を駆使して作ってあります。 LSysDraw.zip

glTranslatef( , , );
glRotatef( , , , );
glPushMatrix();
glPopMatrix();

パターンの翻訳

 
共通パラメータ
llen 移動距離
langle 方向変更の角度

lenfactor
 

F

llenの長さ分上方に線を残して進む

f

llenの長さ分上方に線を残さないで進む

#

線の太さを太くする

!

線の太さを細くする

>

線の長さをlenfactorの値の倍率で長くする

<

線の長さをlenfactorの値の倍率で短くする

@

曲がる方向を逆転する

(

曲がる角度を5度増やす

)

曲がる角度を5度減らす

+

z軸を中心にlangleの値分左回りに、方向を変える

-

z軸を中心にlangleの値分右回りに、方向を変える

[

座標をスタック

]

座標をポップ =座標をスタックしたところまで戻る
   

拡張

} x軸を中心にlangleの値分左回りに、方向を変える
{ x軸を中心にlangleの値分右回りに、方向を変える
| y軸を中心にlangleの値分左回りに、方向を変える

_

y軸を中心にlangleの値分右回りに、方向を変える

使い方:

testApp.h 内

#include "LSysDraw.h"

LSysDraw lsysdraw; // インスタンス

testApp.cpp 内

void testApp::setup() {} 内

lsysdraw.len = 2 ; // 描画要素の長さを変えられます。

lsysdraw.R =1; // 基本描画色RGB (0 - 1.0 )
lsysdraw.G =1;
lsysdraw.B =1;

void testApp::draw() {} 内

lsysdraw.draw(lsys-code); // 引数として、Lsystemで生成される文字列を渡す。

verticalline Boid
undeline

blab_boid.zip

verticalline thread
undeline

SimplePThread クラス

pthread をラップしたものです。

プロジェクトフォルダ内の "src" にSimplePthread.h, SimplePthread.cpp を配置

SimplePthreadクラスを継承して、スレッド実装したクラスを作るのが良いと思います。

#include "SimplePthread.h"

class myTask: public SimplePthread{

ThreadProc(){

//この TreadProcが仮想関数になっていますので
//ここにスレッドで行いたい処理を書く

}

};

 

testApp.h 内

myTask mtask; //インスタンス

testApp.cpp 内

mtask.Begin(); // スレッドスタート

mtask.End()// スレッド終了

 PriPro

いずれもこちらのシリアルドライバのインストールが必要です。

OSX (intel i386)
http://www.ftdichip.com/Drivers/VCP/MacOSX/UniBin/FTDIUSBSerialDriver_v2_2_9.dmg

OSX (ppc)
http://www.ftdichip.com/Drivers/VCP/MacOSX/FTDIUSBSerialDriver_v2_1_9.dmg

Framework版とスタティックライブラリ版を作りました。両方いっぺんに使う必要はありません。

Framework版

PriPro.framework.zip PriPro.Framework 他のframeworkと一緒にシステムにインストールしてください。

HD->System->Library->Frameworks

#include "PriPro/PriPro.h"

として使ってください。

blab_pripro_fw.zip   以下のように配置してください。

pre release v0.05 x-code FAT
├─ apps
│    ├ blabExample
│          ├ blab_pripro_fw
├─ blablib
├─ libs
└─ other

スタティックライブラリ版

PriProlib.zip PriProlib 以下のように配置してください。

pre release v0.05 x-code FAT
├─ apps
├─ blablib
│    ├ PriProlib
│    ├ 
├─ libs
└─ other

blab_pripro.zip スタティックライブラリ板を使った サンプルプロジェクトファイル以下のように配置してください。

pre release v0.05 x-code FAT
├─ apps
│    ├ blabExample
│          ├ blab_pripro
├─ blablib
├─ libs
└─ other

使い方はクワクボ先生の公開しているprocessing用のドライバと一緒です。

 boost serialization 

サンプルプロジェクトファイル blab_serialization.zip

'S' キーと、'R'キーを押してみてください。

dataフォルダに、array1.insect というファイルができているのを確認してください。

ちょっと難しいですが、太字の部分が重要な部分ですので、自分で使用する場合はほぼ、その箇所を変更するだけでよいと思います。

シリアライズしてアーカイブにしたいクラス内のメンバーシリアライズするメンバーとして追加しておく。

今回はInsect の配列、その中のそれぞれのメンバーをシリアライズするため、Insect.h と testApp.h に記述する。

// Insect.h 内

#include <boost/serialization/vector.hpp> // これをインクルード

 //boost serialization
template <typename Archive>
void serialize(Archive &ar, const unsigned int version){

ar & posX;
ar & posY;
ar & dirX;
ar & dirY;
ar & speed;
ar & name;

//ar & *img; // これらをシリアライズするには、
//ar & *font;//ofImageなどのクラスに、
//ar & *sndp;//これと同様のシリアライズの関数を
//ar & *sndp2;//書き込む必要がある

}

次にシリアライズしたアーカイブを保存する関数を実装する。

// testApp.h内

void save(const std::string& path);

// testApp.cpp内

#include <fstream>
#include <ostream>
#include <string>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp> // これらをインクルードしておく。

void
testApp::save(const std::string& path)
{

std::ofstream outPutStream(ofToDataPath(path.c_str()).c_str(), std::ios::out | std::ios::binary );

if(outPutStream.is_open())
{

try{

std::ostringstream archive_stream;
boost::archive::binary_oarchive archive(outPutStream);

archive << (const std::vector<Insect>&) this->insectArray;//この部分がそ れぞれのアプリの設計によって変更されます。

}
catch (std::exception& /*e*/)
{

outPutStream.close();
//return false;
std::cout << "could not save: " << std::endl;

}

outPutStream.close();

std::cout << "saved to: " << path << std::endl;

}

}

次にシリアライズしたアーカイブからデータを読み込む関数を実装する。

// testApp.h内

void load(const std::string& path);

// testApp.cpp内

void
testApp::load(const std::string& path)
{

std::ifstream inPutStream(ofToDataPath(path.c_str()).c_str(), std::ios::in | std::ios::binary );

if(inPutStream.is_open())
{

try{

std::ostringstream archive_stream;
boost::archive::binary_iarchive archive(inPutStream);

archive >> this->insectArray;//この部分がそれぞれのアプリの設計によって 変更されます。

std::cout << "loaded from: " << path << std::endl;

}
catch (std::exception& /*e*/)
{

inPutStream.close();
//return false;
std::cout << "could not save: " << std::endl;

}

inPutStream.close();

}

}

 vector配列内のクラスや構造体のソート

> < の オペレータをオーバーライドしておく。

//testApp.cpp の上方に以下を記述しておく

bool operator<(const Insect& left, const Insect& right) // クラス Insect のメンバーによってソートする。
{

if(left.posY == right.posY) // posY の大小によってソートする想定
{

return left.ID < right.ID;

}else
{

return left.posY < right.posY ;

}

}

bool operator>(const Insect& left, const Insect& right)
{

if(left.posY == right.posY)
{

return left.ID > right.ID;

}else
{

return left.posY > right.posY ;

}

}

// testApp.h 内 でinsectArrayを定義してあるケース

std::vector<Insect> insectArray; //

// testApp.cpp 内 たとえば 

void test::keyreleased(int key) {

if(insectArray.size()>0){

std::sort(insectArray.begin(),insectArray.end()); // イテレータでソート範囲を指定する。
// こうするとposYの大きい順に配列内の順序が入れ替わる。‘

}

}