算術演算子
なんかむずかしそうだお(;^ω^)
算数と同じなんです><
まあそういうことだな
項目作るべきか戸惑ったけど
スクリプトを理解する上ではかなり重要
| LSL |
数学 |
意味 |
| + |
+ |
加算 |
| - |
- |
減算 |
| * |
× |
乗算 |
| / |
÷ |
除算 |
| % |
|
剰余算 |
integer a = 3 * 5;
これで3×5の解(15)が変数aに代入されるってこと
integer b = 2 * a;
こんな風に変数を使っての計算もおk
これだと2*15の解(30)が変数bに代入される
もちろん両方変数でもおk
剰余算っていうのは
余りを出すってことで
integer c = 19 % 5;
19割る5の余り=4 が変数cに代入される
今ある数値の入った変数に足したいって時は
省略して次みたいな書き方もできる
integer a = 3;
a += 5;
こんな感じに書けばaに入ってる3に5が足されて
足された数がaに代入される
つまり
a += 5;
ってのは
a = a + 5;
と同じ処理をしてるってこと
似たようなやつ一覧
| LSL |
使い方 |
省略しない書き方 |
| += |
a += 2; |
a = a + 2; |
| -= |
a -= 2; |
a = a - 2; |
| *= |
a *= 2; |
a = a * 2; |
| /= |
a /= 2; |
a = a / 2; |
| %= |
a %= 2; |
a = a % 2; |
それとあと一つ
変数に1だけ足したい!引きたい!って時は
a++;
a--;
って書くことで
1だけ足す
1だけ引く
って処理をしてくれる
この略した形を世間一般では
インクリメント、デクリメント
って言われてるぞ
integer a = 4;
a--;
//ここの時点でaの中身は3
a++;
a++;
//ここの時点でaの中身は5
このインクリメント、デクリメントは前に書くことも出来て
前に書いた場合は少しだけ処理が違ってくる
integer i = 0;
if(i++){
llOwnerSay("TRUE");
}
integer i = 0;
if(++i){
llOwnerSay("TRUE");
}
上の二つのスクリプトの違う所は前に置くか後ろに置くかってだけなんだけど
実際に動かしてみると上のスクリプトだけTRUEと表示されないのがわかると思う
なんでこうなるかというと
上のスクリプトの場合、if(i)と判断してからi = i + 1という処理をしている
下のスクリプトの場合、i = i + 1という処理をしてからif(i)と判断している
こんな少しの違いでもバグを作る原因には十分なりえるし
使いこなすとかっこいい(当社比)ので覚えておいてね☆
変数による演算の違い
ここまで書いたのはinteger変数を使った計算なんだけど
変数の形によってその演算方法はかなり変わってくるので
ここではその特殊な方法(ついでに変数の特性)を説明
vector
vector変数はプリムの座標、大きさ、速度・・・など
SL内のような3D空間で必要なXYZといった座標、大きさを格納する為に使われる
integer変数とは違い、vectorの中に値を入れたい場合は
vector new_vector = < 100.0 , 150.0 , 200.0 >;
といった様に<>で囲った後に3つの実数値をカンマで区切る
vector = < float , float , float >;
この変数は1つの変数に対して3つの値が入っている
だけどそういった場合、1つだけの値を扱いたいから取り出したいって時がある
そういった場合
new_vector.x
new_vector.y
new_vector.z
と記述することで 1つめの値 2つめ 3つめ と参照できる
3つ値が入ってるってことは今までのintegerの計算方法では説明できないので
計算した結果を見てほしい
vector new_vec = vec1 + vec2
< vec1.x + vec2.x , vec1.y + vec2.y , vec1.z + vec2.z >
vector new_vec = vec1 - vec2
< vec1.x - vec2.x , vec1.y - vec2.y , vec1.z - vec2.z >
float new_dotproduct = vec1 * vec2
内積を求める
返り値が実数形式になってるので注意
( vec1.x * vec2.x ) + ( vec1.y * vec2.y ) + ( vec1.z * vec2.z )
vector new_vec = vec1 % vec2
外積を求める
< vec1.y * vec2.z - vec1.z * vec2.y , vec1.z * vec2.x - vec1.x * vec2.z , vec1.x * vec2.y - vec1.y * vec2.x >
また、ベクトルに関しては便利な関数が用意されているので
複雑な計算を書き始める前にそっちも確認してほしい
float = llVecDist( vector , vector );
2点間の距離を得る
float = llVecMag( vector );
ベクトルの長さを得る
llVecDistと違うのは<0,0,0>からの長さを得られる所
vector = llVecNorm( vector );
単位ベクトルを得る
ベクトルの大きさ1として最適化したベクトルが返る
void llLookAt( vector , float , float );
オブジェクトをvectorの方向に向ける
rotation
rotationは回転を扱う変数
それならx,y,zを回転させればいいんだからvectorで済むんじゃないかお?(^ω^ )
まあまあその説明は以下で
vectorと似てるけどかなり扱いが違ってくる
vectorは1つの変数に3つの要素 x,y,z があったけど
rotationはx,y,zの他にsが加わった形として扱われる
rotation new_rotation = < x , y , z , s>;
それぞれの値の参照方法はvectorと同様に
float rot_y = new_rotation.y;
float rot_s = new_rotation.s;
というようにする
なんで回転を扱う変数値で4つも要素を扱うかというと
XYZの大きさと虚数を使うことで
プログラミングの実行速度が上がるのだとか
詳しくは四元数、又はハミルトン数(英語圏ではquaternion)で調べてくれ
rotation = rotation1 * rotation2
2つの回転を足す
vector = vector1 * rotation1
ベクトルと回転をかける計算
これなんかは特に特殊だけどかなり便利なんで覚えておいてね
rotation1中の座標からvector1の先の位置をvectorに代入してる
もう少しわかりやすくいうと
プリム作って回転させてからローカル座標にして複製
この複製した場所がvectorに相当する値になる(プリム⇒<0,0,0> 回転⇒rotation1 ローカル座標移動⇒vector1)
最終更新:2008年03月19日 14:43