2009年08月11日
位置チェック(LSL)
8/10(月)にペンギンの人と話していたのは、
こんな感じのことです。
これを見てください。
「ボール(の中心点)が半透明の範囲内にあるかどうか」
という判断をどうやってやるかということです。
条件
赤い板は以下の情報を持っている
・赤い板の座標/サイズ/角度
・半透明の空間の座標/サイズ/角度
※この半透明の空間は、赤い板とくっつくように存在します。
また実際には、この半透明Primは存在しません。
可視化するために、Primをおいているだけです。
・ボールの座標
※サイズや角度もわかりますが
この問題とは無関係です
できるだけ単純な方法で解くにはどうするかというのが問題です。
「単純な方法」とは、以下のような基準です。
・コードをたくさん使わない
・処理に時間をかけない
これは、タッチで開くドア等で
タッチした人が、ドアの前の特定の位置にいるかどうか等の判定に使えます。
※なので、タッチは簡単にできるので、一回の処理を軽くしたいわけです
今日は、これを考えてやってました。
お暇な方は、頭の体操的に考えてみてください。
こんな感じのことです。
これを見てください。
「ボール(の中心点)が半透明の範囲内にあるかどうか」
という判断をどうやってやるかということです。
条件
赤い板は以下の情報を持っている
・赤い板の座標/サイズ/角度
・半透明の空間の座標/サイズ/角度
※この半透明の空間は、赤い板とくっつくように存在します。
また実際には、この半透明Primは存在しません。
可視化するために、Primをおいているだけです。
・ボールの座標
※サイズや角度もわかりますが
この問題とは無関係です
できるだけ単純な方法で解くにはどうするかというのが問題です。
「単純な方法」とは、以下のような基準です。
・コードをたくさん使わない
・処理に時間をかけない
これは、タッチで開くドア等で
タッチした人が、ドアの前の特定の位置にいるかどうか等の判定に使えます。
※なので、タッチは簡単にできるので、一回の処理を軽くしたいわけです
今日は、これを考えてやってました。
お暇な方は、頭の体操的に考えてみてください。
LSLCON2010始まりました
LSL Portalで本気で調べてみた(おしまい)
LSL Portalで本気で調べてみた(その10)
LSL Portalで本気で調べてみた(その9)
LSL Portalで本気で調べてみた(その8)
LSL Portalで本気で調べてみた(その7)
LSL Portalで本気で調べてみた(おしまい)
LSL Portalで本気で調べてみた(その10)
LSL Portalで本気で調べてみた(その9)
LSL Portalで本気で調べてみた(その8)
LSL Portalで本気で調べてみた(その7)
Posted by you Xiao at 16:56│Comments(2)
│LSL
この記事へのトラックバック
逆回転を一発かましたっす。もっと簡単にできるんっすかねぇ?他の方の解答に期待っす。
位置判定っす【北国ぺんぎん】at 2009年08月11日 22:39
この記事へのコメント
赤い板をA、半透明の領域をB、青い玉をCとします。
(1)CのAからの相対位置を求める
(2)(1)をAの回転で割る
これで数学的な座標で考えて、回転値0でX=0、Y=0、Z=0を中心とする平面からの相対位置となる。
(3)AのサイズからBの8角のうちのX、Y、Zがともに最小値となる座標と最大値となる座標を計算する
(サイズの半分のX、Yのマイナス値とプラス値。Zは0とBの高さ)
(4)(2)の値が(3)の値の中にあるか判定する
こんな感じでどうでしょう。
コードは以下。
//==============================================================
// ターゲットが指定領域内か判定する
// 1.0.0
// 2009/08/12
// created by sasapy Beck
//--------------------------------------------------------------
// 変数定義
vector BASE_POSITION = ZERO_VECTOR; // 基準面となるリージョン座標
vector BASE_SIZE = ZERO_VECTOR; // 基準面のサイズ
rotation BASE_ROTATION = ZERO_ROTATION; // 基準面のリージョン系回転値
float BASE_HEIGHT = 2.0; // 基準領域の高さ
vector TARGET_POSITION = <200.919, 219.409, 50.496>;
//--------------------------------------------------------------
// Main
default
{
state_entry()
{
// 事前情報として提示されている仮定ですが、一応関数で取得
BASE_POSITION = llGetPos(); // 座標取得
BASE_SIZE = llGetScale(); // サイズ取得
BASE_ROTATION = llGetRot(); // 回転値取得
}
// Touch Event
touch_start(integer num_detected)
{
vector target_offset = ZERO_VECTOR;
vector offset_position = ZERO_VECTOR;
vector point_small = ZERO_VECTOR;
vector point_big = ZERO_VECTOR;
// 相対ベクトル算出
target_offset = TARGET_POSITION - BASE_POSITION;
// 回転値で割って、0回転の場合の相対ベクトルとする
offset_position = target_offset / BASE_ROTATION;
// 基準面のサイズから領域の最小位置(XYZが小さいほう)と最大位置(XYZが大きいほう)の算出
point_small = <-BASE_SIZE.x / 2.0, -BASE_SIZE.y / 2.0, 0.0>;
point_big = < BASE_SIZE.x / 2.0, BASE_SIZE.y / 2.0, BASE_HEIGHT>;
// 計算値確認のため表示
llSay(PUBLIC_CHANNEL, "target_offset: " + (string)target_offset);
llSay(PUBLIC_CHANNEL, "offset_position: " + (string)offset_position);
llSay(PUBLIC_CHANNEL, "point_small: " + (string)point_small);
llSay(PUBLIC_CHANNEL, "point_big: " + (string)point_big );
// 領域内か判定
if( (offset_position.x >= point_small.x) && (offset_position.x <= point_big.x) &&
(offset_position.y >= point_small.y) && (offset_position.y <= point_big.y) &&
(offset_position.z >= point_small.z) && (offset_position.z <= point_big.z)) //>
{
// 領域内の場合
llSay(PUBLIC_CHANNEL, "TRUE");
}
else
{
// 領域外の場合
llSay(PUBLIC_CHANNEL, "FALSE");
}
}
}
//==============================================================
(1)CのAからの相対位置を求める
(2)(1)をAの回転で割る
これで数学的な座標で考えて、回転値0でX=0、Y=0、Z=0を中心とする平面からの相対位置となる。
(3)AのサイズからBの8角のうちのX、Y、Zがともに最小値となる座標と最大値となる座標を計算する
(サイズの半分のX、Yのマイナス値とプラス値。Zは0とBの高さ)
(4)(2)の値が(3)の値の中にあるか判定する
こんな感じでどうでしょう。
コードは以下。
//==============================================================
// ターゲットが指定領域内か判定する
// 1.0.0
// 2009/08/12
// created by sasapy Beck
//--------------------------------------------------------------
// 変数定義
vector BASE_POSITION = ZERO_VECTOR; // 基準面となるリージョン座標
vector BASE_SIZE = ZERO_VECTOR; // 基準面のサイズ
rotation BASE_ROTATION = ZERO_ROTATION; // 基準面のリージョン系回転値
float BASE_HEIGHT = 2.0; // 基準領域の高さ
vector TARGET_POSITION = <200.919, 219.409, 50.496>;
//--------------------------------------------------------------
// Main
default
{
state_entry()
{
// 事前情報として提示されている仮定ですが、一応関数で取得
BASE_POSITION = llGetPos(); // 座標取得
BASE_SIZE = llGetScale(); // サイズ取得
BASE_ROTATION = llGetRot(); // 回転値取得
}
// Touch Event
touch_start(integer num_detected)
{
vector target_offset = ZERO_VECTOR;
vector offset_position = ZERO_VECTOR;
vector point_small = ZERO_VECTOR;
vector point_big = ZERO_VECTOR;
// 相対ベクトル算出
target_offset = TARGET_POSITION - BASE_POSITION;
// 回転値で割って、0回転の場合の相対ベクトルとする
offset_position = target_offset / BASE_ROTATION;
// 基準面のサイズから領域の最小位置(XYZが小さいほう)と最大位置(XYZが大きいほう)の算出
point_small = <-BASE_SIZE.x / 2.0, -BASE_SIZE.y / 2.0, 0.0>;
point_big = < BASE_SIZE.x / 2.0, BASE_SIZE.y / 2.0, BASE_HEIGHT>;
// 計算値確認のため表示
llSay(PUBLIC_CHANNEL, "target_offset: " + (string)target_offset);
llSay(PUBLIC_CHANNEL, "offset_position: " + (string)offset_position);
llSay(PUBLIC_CHANNEL, "point_small: " + (string)point_small);
llSay(PUBLIC_CHANNEL, "point_big: " + (string)point_big );
// 領域内か判定
if( (offset_position.x >= point_small.x) && (offset_position.x <= point_big.x) &&
(offset_position.y >= point_small.y) && (offset_position.y <= point_big.y) &&
(offset_position.z >= point_small.z) && (offset_position.z <= point_big.z)) //>
{
// 領域内の場合
llSay(PUBLIC_CHANNEL, "TRUE");
}
else
{
// 領域外の場合
llSay(PUBLIC_CHANNEL, "FALSE");
}
}
}
//==============================================================
Posted by ささぴ at 2009年08月12日 19:37
やっぱり回転してチェックになりますね
これが一番単純で
いいやり方って結論でいいのかもしれません
これが一番単純で
いいやり方って結論でいいのかもしれません
Posted by you Xiao at 2009年08月12日 20:38