2010年12月24日金曜日

数値入力用ボードっす

課題提出数の予想は7なんっすけど、どのくらい集まるっすかね。
手ごたえが全く無いんっすけど…。
どうもぺんぎんっす( ◎v◎ )


テンキーみたいなのを作ったっす。
llTextBoxが使えるようになったっすけど、「不正な入力」に対する
処理ってかなり面倒なんっすよね。
数値入力に関して、しばらく使えそうっす。

他のヒトにも使ってもらう方法を考えてたっす。
リンクメッセージで値を飛ばす事も考えたっすけど、
それだとMod権限が必要になっちゃうっす。
となるとリンクせずに、オブジェクトからRezして、
say/listenでやり取りする方法がベターじゃないかと考えたっす。

1.llRezObjectでボードをRez
(第5引数のinteger型パラメータに使用するチャンネルを書く)
2.rez_objectイベントにRezしたボードのkeyが渡るので
 使用するチャンネル、ボードのkeyを指定してlistenしておく
3.ボードで入力
4.ボードの「送信ボタン」を押す
5.ボードがon_rezイベントで受け取ったパラメータを使って、
 指定されたチャンネルでsay
6.listenで受け取る

こういう流れになるっす。


これくらいなら「パーツ」として使いやすそうなんっすけど
需要がどこまであるのか分かんないっすね。

2010年12月22日水曜日

rotationが交換可能なときっす(2)

昨日の続きになるっす。
結論まで一気にやるっすね。
どうもぺんぎんっす( ◎v◎ )


昨日の記事を読んでない場合は読んでからの方が良いっすよ。
http://northernpenguin-ex.blogspot.com/2010/12/rotation.html

a * b と b * a の各要素を比較して
x要素について a.y * b.z = a.z * b.y -①
y要素について a.z * b.x = a.x * b.z -②
z要素について a.x * b.y = a.y * b.x -③
ここからスタートっす。

場合分けするっす。
I aがZERO_ROTATIONのとき
b.x、b.y、b.zの値によらず成り立つ。

II a.x≠0 かつ a.y=0 かつ a.z=0 のとき
②より b.z=0
③より b.y=0
②または③より b.xの値によらず成り立つ。
同様にして、
a.x=0 かつ a.y≠0 かつ a.z=0 のとき
 b.x = b.z = 0 のとき、b.yの値によらず成り立つ。
a.x=0 かつ a.y=0 かつ a.z≠0 のとき
 b.x = b.y = 0 のとき、b.zの値によらず成り立つ。

III a.x≠0 かつ a.y≠0 かつ a.z=0 のとき
②より b.z=0
 A b.y=0 のとき
 ③より b.x=0
 ∴ bはZERO_ROTATION
 B b.y≠0 のとき
 ③より b.x≠0
 ③の両辺を b.x * b.y で割ると
 
a.x / b.x = a.y / b.y
 uを0以外の実数として a.x / b.x = a.y / b.y = u とすると
 a.x = u * b.x
 a.y = u * b.y と書けるから
 A = (a.x, a.y, 0), B = (b.x, b.y, 0) とすると
 A = uB となる。
 ∴O = (0, 0, 0)とすると、BはOA上にある
同様にして、a.x≠0 かつ a.y=0 かつ a.z≠0 のとき
a.x=0 かつ a.y≠0 かつ a.z≠0 のときも
  bはZERO_ROTATION または
  BはOA上にある。

IV a.x≠0 かつ a.y≠0 かつ a.z≠0 のとき
 A b.z=0のとき
 ①より b.y=0
 ②より b.x=0
 ∴ bはZERO_ROTATION
 B b.z≠0のとき
 ①より b.y≠0
 ②より b.x≠0
 ①の両辺を b.y * b.z で割ると
 a.y / b.y = a.z / b.z -④
 ②の両辺を b.x * b.x で割ると
 a.z / b.z = a.x / b.x -⑤
 ③の両辺を b.x * b.y で割ると
 a.x / b.x = a.y / b.y -⑥
 ④⑤⑥より uを0以外の実数として
 b.x = u * a.x
 b.y = u * a.y
 b.z = u * a.z と書けるから
 A = (a.x, a.y, a.z), B = (b.x, b.y, b.z) とすると
 A = uB となる。
 ∴O = (0, 0, 0)とすると、BはOA上にある


これで場合分けが完了っす。
キーは「BはOA上にある」、これっす。
IIもa.x = u * b.x のカタチに出来るので、これもまとめられるっす。

OAとかOBっていうのは回転軸を表すベクトルっす。
というわけで結論は
「回転軸が同じなら交換可能」
っていうのが分かったっす。

2010年12月21日火曜日

rotationが交換可能なときっす

rotationではa * b と b * a が一致しないことが多いんっすけど、
逆に一致することもあるわけっす。
どんな条件があるのか考えてみたっす。
どうもぺんぎんっす( ◎v◎ )


まず、明らかなのは
 ・a = b のとき
 ・b = ZERO_ROTATION / a のとき
これらは見た瞬間に分かるっすね。
他の場合が無いか、考えてみるっす。

作戦はa * b と b * a を計算して、x、y、z、sの各要素を比較するっす。
式が4本出るので、そこから考えて行くっす。
とりあえず積を出すっす。
どっちか片方書けば、もう片方はaとbを入れ替えれば良いっすね。
というわけでa * bを計算するっす。
c = a * b とすると、
c.x = a.s * b.x + a.x * b.s + a.y * b.z - a.z * b.y
c.y = a.s * b.y + a.y * b.s + a.z * b.x - a.x * b.z
c.z = a.s * b.z + a.z * b.s + a.x * b.y - a.y * b.x
c.s = a.s * b.s - a.x * b.x - a.y * b.y - a.z * b.z

s要素はaとbを入れ替えても同じになるっすね。
ということは実質3本の式になるっす。
x、y、z要素についてもaとbを入れ替えたら同じになる部分は
緑で表示しておいたっす。
比較するときに両方で出てくるので、消える部分になるっす。

a * b と b * a の各要素を比較して
x要素について a.y * b.z = a.z * b.y -①
y要素について a.z * b.x = a.x * b.z -②
z要素について a.x * b.y = a.y * b.x -③
①②③を満たすようなbを選べばa * bとb * a は一致するっす。


もうちょっと変形しないと見えないっすね。

2010年12月17日金曜日

福袋っす(2)

LSLで無茶してみましたシリーズ最新作っすね。
自分の方法を載せておくっす。
問題点も書いておくっすね。
どうもぺんぎんっす( ◎v◎ )


何をやるかは前回の記事参照っす。
深さ優先探索で書いてみたっす。


list CONTENTS_AND_VALUES = // 景品(?)名, 価値 [価値の大きいもの順!]
["product10", 50,
"product09", 50,
"product08", 40,
"product07", 40,
"product06", 30,
"product05", 30,
"product04", 20,
"product03", 20,
"product02", 10,
"product01", 10];
integer RANGE_MIN = 90; // 設定値の下限
integer RANGE_MAX = 110; // 設定値の上限

integer item_count; // コンテンツにある景品(?)総数

list bag; // 袋の中身
list result; // 探索結果格納用

// 初期化
Init()
{
item_count = llGetListLength(CONTENTS_AND_VALUES) / 2;
}
// 探索制御
integer Search()
{
integer i;
for(i = 0; i < item_count; ++i)
{
bag = [i];
DPS(i, llList2Integer(CONTENTS_AND_VALUES, i * 2 + 1));
}
if(result)
{
return TRUE;
}
else
{
return FALSE;
}
}
// 深さ優先探索
integer DPS(integer prev, integer total)
{
integer i;
integer value;

for(i = prev + 1; i < item_count; ++i)
{
// ピックした後の状態
bag = [i] + bag;

// 評価値を計算
value = llList2Integer(CONTENTS_AND_VALUES, i * 2 + 1);
total += value;

// 再帰
if(IsRange(total) || DPS(i, total))
{
result = [llDumpList2String(bag, ",") + "合計" + (string)total] + result;
}

// ピック前に戻す
total -= value;
bag = llDeleteSubList(bag, 0, 0);
}
return FALSE;
}
// 評価
integer IsRange(integer value)
{
if(value >= RANGE_MIN)
{
if(value <= RANGE_MAX)
{
return TRUE;
}
}
return FALSE;
}

default
{
state_entry()
{
Init();
if(Search())
{
llOwnerSay((string)llGetListLength(result));
llOwnerSay(llDumpList2String(result, "\n"));
}
}
}


結果は全部まとめて1つのlistに格納しておいて
ダンプしてOwnerSayさせてるっすから、途中で切れちゃうかもっす。
関数DPS内のresultに結果を入れてる部分で
逐一OwnerSayさせた方が良いかもっすね。

60通りの組み合わせが出力されるはずっす。
これで全部網羅してるかというと、そうではないっす。

0,1合計100
っていうパターンがあるっすよね。
範囲内に収まってるっすけど、まだイケるっすね。
8番目または9番目の価値10を加えることも出来るっす。
自分の方法はこのオマケの部分を考慮してないっす。


また改良するかもしれないっすけど、とりあえずこんなもんで…

2010年12月16日木曜日

福袋っす(1)

提出された課題をチェックしてたらこんな時間っす。
今回のネタに関するスクリプトは書けてないっす。
明日になるっすね。
どうもぺんぎんっす( ◎v◎ )


とっても面白そうなネタが投下されたっす。
福袋なんっすけど、もちろん自分の商品じゃないっすよ。
福袋を箱詰めする際の、その組み合わせ方についてっす。
今日は問題提示だけになりそうっす。

中に入れるモノにはそれぞれ「価値」が割り振られてるっす。
いくつかモノを組み合わせて価値の合計が「設定値」の
範囲内に収めたいわけっす。
ついでにその組み合わせ方を列挙もしたいっす。
あ、同じモノを2つ以上入れるのはナシっす。
組み合わせ方のパターンは膨大になって面倒なので
スクリプトで解かせようというものっす。

具体的に問題を見て行くっす。
list CONTENTS_AND_VALUES = // モノの名前, 重み
[
   "product01", 10,
"product02", 10,
"product03", 20,
"product04", 20,
"product05", 30,
"product06", 30,
"product07", 40,
"product08", 40,
"product09", 50,
"product10", 50
];
こんな感じのlistが与えられるっす。
要素数も変わると思ってた方が良いっすね。
これと「設定値」、例えば[合計90から110]が共に与えられた時
考えられる組み合わせを全部出せという問題っす。
組み合わせの1つとしては
product03 20
product06 30
product10 50
で、価値を合計すると100になるので設定値を満たすっす。

パターン数は
モノを1個選ぶ……10C1
モノを2個選ぶ……10C2
モノを3個選ぶ……10C3
 ・
 ・
 ・
モノを10個選ぶ……10C10
これの合計数になるっす。(面倒なので計算はしてないっす)
モノが10種類なので大したことないんっすけど、
20種類、30種類となるとかなりの数になるっす。

product03-product06-product10の組み合わせを発見したら、
product03-product10-product06
product06-product03-product10
product06-product10-product03
product10-product06-product03
product10-product03-product06
っていう組み合わせも見つけちゃう可能性があるっす。
これは価値大→価値小の順に探索を進めて行けば
防げるっす。同価値の場合はlistのインデックス順っす。
product03-product06-product10のケースだと
product10-product06-product03の1通りになるっす。


自分は深さ優先探索でやろうと思ってるんっすけど
皆さんならどうやるっすかね?

2010年12月15日水曜日

新しい土地を探さないとっす

多倍長演算はロマンあふれる円周率計算と共に
着々と進んでるっす。
無いと困るものでは無いんっすけどね。
あれば便利かも程度のもんっす。
どうもぺんぎんっす( ◎v◎ )


いろいろあって、自宅兼作業場兼店舗を撤去したっす。
これで自分の借りてる土地がなくなったわけっす。

久しぶりに土地が無い状態に戻ったわけなんっすけど、
inするときに「ホーム」を選べないのは地味に痛いっす。
MarketplaceのMagic Boxも置くところが無いのも
痛いと言えば痛いっす。
現物が置けないので、Magic Box単体では置きたくないっす。


月々L$1,000で1,024sqmくらいの土地があれば教えてくださいっす。
あ、ベーシックアカウントなので、レンタルっす。

2010年12月12日日曜日

もうちょっと精度ほしいっすよね

土曜日の「いつもの会」は新関数についてちょっとやったっす。
講座の受講者が誰か来るかと思ってたんっすけど、
結局誰も来なかったっす。興味無いんっすかね?
どうもぺんぎんっす( ◎v◎ )


LSLのfloat型は単精度浮動小数っす。
C言語などでのdouble型に相当する型がLSLには存在しないっす。
integer→float→integerとキャストすると元の値と違ったり
することもあって、何かと不便っす。

いっそのこと多倍長演算の仕組みを作れば良いんっすけど、
それは大げさ過ぎる気がするっす。
作ったとしても、他のスクリプトからは参照できないわけっすから、
各スクリプトファイルに作った関数をコピペしていくことになって、
何やってるか分かんなくなるっす。


C#が来てくれればある程度の問題は片付くと思うんっすけど
いつになるか分かんないっすから、大げさにやるっすかねぇ。
多倍長演算、やってみるっす。

2010年12月11日土曜日

10.11.30サーバーからの新関数っす

ちょっと乗り遅れた感があるっすね。
新しく加わった関数より、新しく加わったフラグが大きいっす。
両方とも記事で触れるっすけどね。
どうもぺんぎんっす( ◎v◎ )


もう来てる(=使える)ので、リンクは関数のページにしておくっす。
まずは新関数のllGetEnvからっす。
この関数はRegionのバージョン情報を取得する関数になるっす。
使い道はそんなに無いとは思うんっすけど、
changedイベントでリスタートを検知したついでに
バージョンチャンジによるリスタートなのか、それとも
オーナーやエステートマネージャーによってリスタートされてのかを
判別するのには使えそうっす。
判別した後のことは知らないっすよ。

もう1つがllGetObjectDetailsの追加フラグっす。
追加されたフラグは3つあるっす。

OBJECT_RUNNING_SCRIPT_COUNT
  オブジェクトに入ってる「実行中」のスクリプトの本数を
  取得するためのフラグっす。
OBJECT_TOTAL_SCRIPT_COUNT
  オブジェクトに入ってるスクリプトの本数を取得できるっす。
  OBJECT_RUNNING_SCRIPT_COUNTとは違い、
  「実行中」でないスクリプトもカウントするっす。
OBJECT_SCRIPT_MEMORY
  オブジェクト中のスクリプトが消費しているメモリ量を
  バイト単位で取得するためのフラグっす。

便利なのは引数にアバターのkeyを入れることも出来て、
装着物の合算値を得ることが出来ることっす。
データを集めてみても良いかもっすね。


まだ来てない関数にllCastRayっていうのがあるっす。
Ray(光線)をCast(投げる)ってことっすから、パーティクルっぽいっす。
collisionみたいな、sensorみたいな…のを関数でやるっぽいっす。
ベータグリッドで適用済みのRegionもあるみたいっすから、
試してみてくださいっす。
Free Avatar