Feel free to report problems and request or provide enhancements.
Initial post follows.
----------------------------------------------------------------------------------------------------------------------
I've been trying to understand in depths spherical coordinates but I'm failing in details I think.
Anyway searching both online and Ogre forum was useful, but I remarked that no type representing such coordinates was ever provided.
So I decided to make one for my own usage, but it seems it could be useful for a lot of other users.
I will certainly either make a PR to add this type to OgreMain, or make a wiki article for it, OR make a repository and put everything there and have a Wiki page link to it or something like that. I don't know what do you think might be the more useful?
Here is what I have so far:
Code: Select all
/** Spherical coordinates vector, used for spherical coordinate and transformations. */
struct SphereVector
{
Ogre::Real radius; ///< Rho or Radius is the distance from the center of the sphere.
Ogre::Radian theta; ///< Theta is the angle around the x axis, values range from 0 to PI.
Ogre::Radian phi; ///< Phi is the angle around the x axis, values range from 0 to 2PI.
friend SphereVector operator-( const SphereVector& value )
{
SphereVector result;
result.radius = -value.radius;
result.theta = -value.theta;
result.phi = -value.phi;
return result;
}
friend SphereVector operator+( const SphereVector& left, const SphereVector& right )
{
SphereVector result;
result.radius = left.radius + right.radius;
result.theta = left.theta + right.theta;
result.phi = left.phi + right.phi;
return result;
}
friend SphereVector operator-( const SphereVector& left, const SphereVector& right )
{
return left + (-right);
}
SphereVector& operator+=( const SphereVector& other )
{
*this = *this + other;
return *this;
}
SphereVector& operator-=( const SphereVector& other )
{
*this = *this - other;
return *this;
}
/// Rotate the position around the center of the sphere.
friend SphereVector operator*( const SphereVector& sv, const Ogre::Quaternion& rotation )
{
???
}
/// Rotate the position around the center of the sphere.
friend SphereVector operator*( const Ogre::Quaternion& rotation, const SphereVector& sv ) { return sv * rotation; }
/// Rotate the position around the center of the sphere.
SphereVector& operator*=( const Ogre::Quaternion& rotation )
{
*this = *this * rotation;
return *this;
}
/** @return a Cartesian vector coordinate from the spherical coordinate around the provided center position. */
Ogre::Vector3 to_position_around( const Ogre::Vector3& sphere_center ) const
{
// NOTE: All online examples are based on +Z being up, but in Ogre/OGL +Y is up!
Ogre::Vector3 result;
result.z = radius * Ogre::Math::Sin( theta ) * Ogre::Math::Sin( phi );
result.x = radius * Ogre::Math::Sin( theta ) * Ogre::Math::Cos( phi );
result.y = radius * Ogre::Math::Cos( theta );
return sphere_center + result;
}
/** @return a rotation from the provided axis to the spherical coordinate. */
Ogre::Quaternion rotation_from( const Ogre::Vector3& center, const Ogre::Vector3& axis ) const
{
const auto position_from_sphere_pos = to_position_around( center );
return axis.getRotationTo( position_from_sphere_pos );
}
};
1. ignore the naming, coding convention and use of auto for now, it's code used outside Ogre but I'll rewrite it to match Ogre's convention once it works well;
2. are the comments correct for the members? I'm having trouble with which theta or phi is around which axis in the case of y being the up vector. All the documentation online, Ogre forum included, describe the case for z being the up vector. This is very confusing for me but I think I might have got it right, so I need confirmation on this. (sorry I'm very slow at maths because I don't trust myself at all)
3. is to_position_around() implementation correct? From my tests it seems to be, but I think it's easy to get wrong.
4. same question rotation_from()
5. How should I implement rotation around the center using a quaternion? (see opertor*() ) I'm totally lost on this one but I need to use it systematically with this type.
6. Are there important missing operators or functions you want to see? I added operator*( Real) before but it made no sense so I removed it (and I wouldn't use it anyway). Also, I'm wondering if equality operators would make sense and if yes should I do like Ogre maths objects and use the natural == operator instead of Ogre::Math::RealEqual()?
7. Any comments are welcome.
Thanks for your attention and time.
I hope this will be useful, but it will certainly need upgrades.