Irrlichtエンジンを使用してフリーフロー2Dラスタ画像を空間に配置する関数を作成したいと考えています。これのインスピレーションは、Rパッケージrglの関数rgl::show2dです。 Rの実装例はhereです。Irrlicht:4つのコーナー座標に基づいて3D空間に2D画像を描画する
入力データは、画像へのパスと、各プロット矩形の四隅の座標テーブルに限定されるべきです。
イルリヒトでこれを実現するための私の最初の、かなり原始的かつ最終的には失敗したアプローチ:
キューブを作成します。
ISceneNode * picturenode = scenemgr->addCubeSceneNode();
は片側フラット化:
picturenode->setScale(vector3df(1, 0.001, 1));
をテクスチャとして画像を追加します。
picturenode->setMaterialTexture(0, driver->getTexture("path/to/image.png"));
4つのコーナー座標の中央の位置にフラットキューブを配置します。私はちょうど小さな関数position_calc()
で3つの軸すべての平均座標を計算します。
vector3df position = position_calc(rcdf); picturenode->setPosition(position);
、四隅の座標によって定義される平面の法線を計算し、結果を正規化し、何とか回転角度に得られたベクターを変換しようとすることで、オブジェクトの回転を決定します。
vector3df normal = normal_calc(rcdf);
vector3df angles = (normal.normalize()).getSphericalCoordinateAngles();
picturenode->setRotation(angles);
このソリューションでは、期待した結果が得られません。回転計算が間違っています。このアプローチでは、画像をコーナー座標に正確に拡大することもできません。
ワークフローを修正するにはどうすればよいですか?それとも、私が気付いていないイルリヒトでこれを達成するためのより良い方法がありますか?
編集:私は、私はほとんどそこだと信じて@spugに感謝。私はquaternionsが既にIrrlichtで利用可能であるため、彼の方法2を実装しようとしました。ここで私は回転を計算するために思い付いたものです:
#include <Rcpp.h>
#include <irrlicht.h>
#include <math.h>
using namespace Rcpp;
core::vector3df rotation_calc(DataFrame rcdf) {
NumericVector x = rcdf["x"];
NumericVector y = rcdf["y"];
NumericVector z = rcdf["z"];
// Z-axis
core::vector3df zaxis(0, 0, 1);
// resulting image's normal
core::vector3df normal = normal_calc(rcdf);
// calculate the rotation from the original image's normal (i.e. the Z-axis)
// to the resulting image's normal => quaternion P.
core::quaternion p;
p.rotationFromTo(zaxis, normal);
// take the midpoint of AB from the diagram in method 1, and rotate it with
// the quaternion P => vector U.
core::vector3df MAB(0, 0.5, 0);
core::quaternion m(MAB.X, MAB.Y, MAB.Z, 0);
core::quaternion rot = p * m * p.makeInverse();
core::vector3df u(rot.X, rot.Y, rot.Z);
// calculate the rotation from U to the midpoint of DE => quaternion Q
core::vector3df MDE(
(x(0) + x(1))/2,
(y(0) + y(1))/2,
(z(0) + z(1))/2
);
core::quaternion q;
q.rotationFromTo(u, MDE);
// multiply in the order Q * P, and convert to Euler angles
core::quaternion f = q * p;
core::vector3df euler;
f.toEuler(euler);
// to degrees
core::vector3df degrees(
euler.X * (180.0/M_PI),
euler.Y * (180.0/M_PI),
euler.Z * (180.0/M_PI)
);
Rcout << "degrees: " << degrees.X << ", " << degrees.Y << ", " << degrees.Z << std::endl;
return degrees;
}
結果はほとんど正しいのですが、1つの軸上の回転が間違っています。これを修正する方法はありますか、実装に本質的に欠陥がありますか?
これは、今の結果です。ポイントは予想されるコーナーポイントをマークします。私はこれを行うには、2つの方法を考えてきました
何が 'rcdf'ですか? – meowgoesthedog
私は[Rcpp](https://cran.r-project.org/web/packages/Rcpp/index.html)フレームワークを使用しています。これはDataFrameオブジェクトで、この場合は3列4行のテーブルを表します。 4つのコーナーポイントのx、y、z座標。申し訳ありません - 私はこれを記述するのを忘れました。 – nevrome
これの問題は、* 2 *球座標の角度だけです。 'normal'の周りの画像の回転を指定するのに3番目が必要です。これはロールと呼ばれます。あなたは少なくとも、正しい方向を指すように画像*平面を得ることができますか? – meowgoesthedog