【Unity】Mathd系列(四)Double型Quaternion

这篇博客探讨了在Unity中使用Double型Quaternion的原因,虽然float型精度通常足够,但作者仍然详细介绍了Double型的实现。文章指出在实现某些特定功能如FromToRotation时遇到困难,期待社区专家提供帮助。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    其实,单纯要说四元数float型的精度完全够用,并不需要写成double型。不过前面的都写了,总要进行计算啊!不写不行啊。

    Quaternion写起来有些难度,查找了一些资料后仍有一个FromToRotation方法未实现,求大神前来帮助~

Quaterniond:

/// Quaterniond.cs
/// 
/// The double type version of the Unity struct Quaternion.
/// It can solve the problem that the float type may not be accurate enough.
/// Function LookAt is unimplmented.
/// 
/// Unity Quaternion结构体的double版实现,以解决float型精度可能不够的问题。其中FromToRotation方法暂未实现。
/// 
/// Created by D子宇 on 2018.3.17 
/// 
/// Email: darkziyu@126.com
using System;
using UnityEngine.Internal;

namespace Mathd
{
    public struct Quaterniond
    {
        #region public members

        public double x;
        public double y;
        public double z;
        public double w;

        #endregion

        #region constructor

        public Quaterniond(double p_x, double p_y, double p_z, double p_w)
        {
            x = p_x;
            y = p_y;
            z = p_z;
            w = p_w;
        }

        #endregion

        #region public properties

        public double this[int index]
        {
            get
            {
                switch (index)
                {
                    case 0:
                        return x;
                    case 1:
                        return y;
                    case 2:
                        return z;
                    case 3:
                        return w;
                    default:
                        throw new IndexOutOfRangeException("Invalid Quaterniond index!");
                }
            }
            set
            {
                switch (index)
                {
                    case 0:
                        x = value;
                        break;
                    case 1:
                        y = value;
                        break;
                    case 2:
                        z = value;
                        break;
                    case 3:
                        w = value;
                        break;
                    default:
                        throw new IndexOutOfRangeException("Invalid Quaterniond index!");
                }
            }
        }

        public static Quaterniond identity
        {
            get
            {
                return new Quaterniond(0, 0, 0, 1);
            }
        }

        public Vector3d eulerAngles
        {
            get
            {
                Matrix4x4d m = QuaternionToMatrix(this);
                return (MatrixToEuler(m) * 180 / Math.PI);
            }
            set
            {
                this = Euler(value);
            }
        }

        #endregion

        #region public functions

        /// <summary>
        /// 夹角大小
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static double Angle(Quaterniond a, Quaterniond b)
        {
            double single = Dot(a, b);
            return Math.Acos(Math.Min(Math.Abs(single), 1f)) * 2f * (180 / Math.PI);
        }
        /// <summary>
        /// 轴向旋转
        /// </summary>
        /// <param name="angle"></param>
        /// <param name="axis"></param>
        /// <returns></returns>
        public static Quaterniond AngleAxis(double angle, Vector3d axis)
        {
            axis = axis.normalized;
            angle = angle / 180D * Math.PI;

            Quaterniond q = new Quaterniond();

            double halfAngle = angle * 0.5D;
            double s = Math.Sin(halfAngle);

            q.w = Math.Cos(halfAngle);
            q.x = s * axis.x;
            q.y = s * axis.y;
            q.z = s * axis.z;

            return q;
        }
        /// <summary>
        /// 点乘
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static double Dot(Quaterniond a, Quaterniond b)
        {
            return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
        }
        /// <summary>
        /// 欧拉角转四元数
        /// </
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值