এটি করার একাধিক উপায় রয়েছে। আপনি আপনার অবতারের সাথে সম্পর্কিত নিখুঁত ওরিয়েন্টেশন বা ঘূর্ণন গণনা করতে পারেন, তার অর্থ আপনার নতুন ওরিয়েন্টেশন = অবতার ওরিয়েন্টেশন * কিউ। এখানে দ্বিতীয়টি হল:
আপনার অবতারের ইউনিট ফরোয়ার্ড ভেক্টর এবং ইউনিট ভেক্টরকে অবতার থেকে লক্ষ্য হিসাবে লক্ষ্য হিসাবে নিয়ে যাওয়ার জন্য ক্রস পণ্যটি গ্রহণ করে আবর্তনের অক্ষটি গণনা করুন:
vector newForwardUnit = vector::normalize(target - avatarPosition);
vector rotAxis = vector::cross(avatarForwardUnit, newForwardUnit);
বিন্দু-পণ্য ব্যবহার করে ঘূর্ণন কোণ গণনা করুন
float rotAngle = acos(vector::dot(avatarForwardUnit, newForwardUnit));
রোটএক্সিস এবং রোটএঙ্গেল ব্যবহার করে কোয়াটারিয়ন তৈরি করুন এবং এটিকে অবতারের বর্তমান ওরিয়েন্টেশন দিয়ে গুণ করুন
quaternion q(rotAxis, rotAngle);
quaternion newRot = avatarRot * q;
আপনার যদি অবতারের বর্তমান ফরোয়ার্ড ভেক্টরটি খুঁজে পেতে সহায়তা প্রয়োজন হয় তবে 1 এর জন্য ইনপুটটি কেবল শুট করুন :)
সম্পাদনা: নিখুঁত ওরিয়েন্টেশন গণনা করা কিছুটা সহজ, অবতারদের ফরোয়ার্ড ভেক্টরের পরিবর্তে পরিচয়-ম্যাট্রিক্সের ফরোয়ার্ড ভেক্টরটি 1 এবং 2 এর ইনপুট হিসাবে ব্যবহার করুন)। এবং এটি 3 এ গুণ করবেন না, পরিবর্তে এটি সরাসরি নতুন অভিযোজন হিসাবে ব্যবহার করুন:newRot = q
গুরুত্বপূর্ণ লক্ষণীয়: সমাধানটির ক্রস-প্রোডাক্টের প্রকৃতির কারণে 2 টি অসঙ্গতি রয়েছে:
ফরোয়ার্ড ভেক্টরগুলি সমান হলে। সমাধান এখানে সহজভাবে পরিচয় চতুর্দশী ফিরে
যদি ভেক্টরগুলি ঠিক বিপরীত দিকে নির্দেশ করে। এখানে সমাধানটি হল আবর্তন অক্ষটি আবর্তন অক্ষ এবং 180.0 ডিগ্রি কোণ হিসাবে অবতারগুলি অক্ষর ব্যবহার করে চৌম্বক তৈরি করা।
এখানে C ++ এর বাস্তবায়ন যা এই প্রান্তের কেসগুলি যত্ন করে। এটিকে সি # তে রূপান্তর করা সহজ হওয়া উচিত।
// returns a quaternion that rotates vector a to vector b
quaternion get_rotation(const vector &a, const vector &b, const vector &up)
{
ASSERT_VECTOR_NORMALIZED(a);
ASSERT_VECTOR_NORMALIZED(b);
float dot = vector::dot(a, b);
// test for dot -1
if(nearly_equal_eps_f(dot, -1.0f, 0.000001f))
{
// vector a and b point exactly in the opposite direction,
// so it is a 180 degrees turn around the up-axis
return quaternion(up, gdeg2rad(180.0f));
}
// test for dot 1
else if(nearly_equal_eps_f(dot, 1.0f, 0.000001f))
{
// vector a and b point exactly in the same direction
// so we return the identity quaternion
return quaternion(0.0f, 0.0f, 0.0f, 1.0f);
}
float rotAngle = acos(dot);
vector rotAxis = vector::cross(a, b);
rotAxis = vector::normalize(rotAxis);
return quaternion(rotAxis, rotAngle);
}
সম্পাদনা: মার্কের এক্সএনএ কোডটির সংশোধিত সংস্করণ
// the new forward vector, so the avatar faces the target
Vector3 newForward = Vector3.Normalize(Position - GameState.Avatar.Position);
// calc the rotation so the avatar faces the target
Rotation = Helpers.GetRotation(Vector3.Forward, newForward, Vector3.Up);
Cannon.Shoot(Position, Rotation, this);
public static Quaternion GetRotation(Vector3 source, Vector3 dest, Vector3 up)
{
float dot = Vector3.Dot(source, dest);
if (Math.Abs(dot - (-1.0f)) < 0.000001f)
{
// vector a and b point exactly in the opposite direction,
// so it is a 180 degrees turn around the up-axis
return new Quaternion(up, MathHelper.ToRadians(180.0f));
}
if (Math.Abs(dot - (1.0f)) < 0.000001f)
{
// vector a and b point exactly in the same direction
// so we return the identity quaternion
return Quaternion.Identity;
}
float rotAngle = (float)Math.Acos(dot);
Vector3 rotAxis = Vector3.Cross(source, dest);
rotAxis = Vector3.Normalize(rotAxis);
return Quaternion.CreateFromAxisAngle(rotAxis, rotAngle);
}
0*(rotation A) + 1*(rotation B)
- অন্য কথায়, আপনি কেবল ঘূর্ণনটি বি ঘূর্ণন বিতে দীর্ঘ পথ নির্ধারণ করছেন। ঘূর্ণনটি (0% <x <100%) এর মধ্যবর্তী স্থানে দেখতে কেমন হবে তা নির্ধারণের জন্যই স্লের্প।