LoginSignup
1
1

行列を用いて、砲台を回してみた。

Last updated at Posted at 2023-12-14

はいどーもー。バーチャルDXライブラリストのキズナア i ...(殴)

冗談は置いておいて、初めまして、SHIBRBKと申します。
DXライブラリで主に3Dを扱ってます。

今回は一応初投稿ということで、文やコードが拙いと思いますが、そこはまぁ、多めにお願いします。

事前準備品
  戦車のモデル(砲塔と車体のフレームが別のやつ)
  DXライブラリ

コード
int tankModelid_ = MV1LoadModel("Tank.mv1")

MATRIX mat = 
MV1GetFrameBaseLocalMatrix(tankModelid_, フレーム番号);// 指定のフレ-
ムの初期状態での座標変換行列を取得する.

VECTOR scale=MGetSize(mat);//大きさ

MATRIX matscl = MGetScale(scale);// 拡大行列を取得する

VECOTR pos = MGetTranslateElem(mat);//行列の平行移動成分を取得する

VECTOR TurretLocalPos = TurretQua.PosAxis(/*砲台が車体から離れた座標分補完させる(ここは直値になった)*/);

pos = VAdd(pos, TurretLocalPos);

MATRIX matPos=MGetTranslate(pos);
mat = MMult(mat, matscl);//大きさ
mat = MMult(mat, TurretQua.ToMatrix());//回転
mat = MMult(mat, matPos);//位置

MV1SetFrameUserLocalMatrix(tankModelid_,フレーム番号, mat);

クォーターニオンクラス作ったほうがいいかも…

クォーターニオン.h
public:

Quaternion::Quaternion(double ww, double wx, double wy, double wz)

//座標を回転させる
static VECTOR PosAxis(const Quaternion& q, VECTOR pos);
VECTOR PosAxis(VECTOR pos) const;

// クォータニオンから行列へ変換
static MATRIX ToMatrix(const Quaternion& q);
MATRIX ToMatrix(void) const;

private:
double w; 
double x;
double y;
double z;
クォーターニオン.cpp
Quaternion::Quaternion(double ww, double wx, double wy, double wz)
{
    w = ww;
    x = wx;
    y = wy;
    z = wz;
}

VECTOR Quaternion::PosAxis(const Quaternion& q, VECTOR pos)
{
    // 位置情報に回転情報を反映させる
    // pos' = q・pos・q(-1)
    Quaternion tmp = Quaternion();
    tmp = tmp.Mult(q);
    tmp = tmp.Mult(Quaternion(0.0f, pos.x, pos.y, pos.z));
    tmp = tmp.Mult(q.Inverse());
    return { (float)tmp.x, (float)tmp.y, (float)tmp.z };
}

VECTOR Quaternion::PosAxis(VECTOR pos) const
{
    return PosAxis(Quaternion(w, x, y, z), pos);
}

MATRIX Quaternion::ToMatrix(const Quaternion& q)
{
    MATRIX mat;

    float sx = static_cast<float>(q.x * q.x) * 2.0f;
    float sy = static_cast<float>(q.y * q.y) * 2.0f;
    float sz = static_cast<float>(q.z * q.z) * 2.0f;
    float cx = static_cast<float>(q.y * q.z) * 2.0f;
    float cy = static_cast<float>(q.x * q.z)* 2.0f;
    float cz = static_cast<float>(q.x * q.y)* 2.0f;
    float wx = static_cast<float>(q.w * q.x)* 2.0f;
    float wy = static_cast<float>(q.w * q.y) * 2.0f;
    float wz = static_cast<float>(q.w * q.z) * 2.0f;

    mat.m[0][0] = 1.0f - (sy + sz);	mat.m[0][1] = cz + wz;			mat.m[0][2] = cy - wy;			mat.m[0][3] = 0.0f;
    mat.m[1][0] = cz - wz;			mat.m[1][1] = 1.0f - (sx + sz);	mat.m[1][2] = cx + wx;			mat.m[1][3] = 0.0f;
    mat.m[2][0] = cy + wy;			mat.m[2][1] = cx - wx;			mat.m[2][2] = 1.0f - (sx + sy);	mat.m[2][3] = 0.0f;
    mat.m[3][0] = 0.0f;				mat.m[3][1] = 0.0f;				mat.m[3][2] = 0.0f;				mat.m[3][3] = 1.0f;
    //mat.m[3][0] = trans.x;				mat.m[3][1] = trans.y;				mat.m[3][2] = trans.z;				mat.m[3][3] = 1.0f;

    return mat;
}

MATRIX Quaternion::ToMatrix(void) const
{
    return ToMatrix(Quaternion(w, x, y, z));
}

一応自分のプロジェクトから引っ張ってきたのですが、まだ直せてないところもあるます!

まさかりかついだ金太郎もバンバン飛ばしちゃってください。

色々修正したものはしばらくしたら上げますのでお待ちください

1
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1