定点绕定轴旋转

Posted zwcoding

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了定点绕定轴旋转相关的知识,希望对你有一定的参考价值。

通过两个已知点,绕定轴旋转360次,每次旋转一度,获得360个点,一次相连,可以获得一个近似圆。
网上找的公式基本都是左手坐标系下的选择公式,故而进行了多次坐标转换

 

1、3.2版本

public static List<Vector3d> Translate(List<Vector3> list)
        {
            List<Vector3d> zuoshou = new List<Vector3d>();//存左手坐标系下的各点坐标
            List<Vector3d> shijiezuobiao = new List<Vector3d>();//存世界坐标系下的各点坐标
            List<Vector3d> jieguoweidu = new List<Vector3d>();//存世界坐标转换过来的经纬度坐标
            List<Vector3d> zuizhong = new List<Vector3d>();//存经纬度不变,高程设为新值的经纬度坐标
            //由双击球体获取点位置和球心三点生成平面,过圆心垂直此平面的法向量,作为旋转轴
            Vector3 p1 = new Vector3(list[0].X, list[0].Z, list[0].Y);
            Vector3 p2 = new Vector3(list[1].X, list[1].Z, list[1].Y);
            Vector3 xuanzhuanzhou = new Vector3();
            xuanzhuanzhou.X = 1;
            xuanzhuanzhou.Y = (p1.X * p2.Z - p2.X * p1.Z) / (p1.Z * p2.Y - p2.Z * p1.Y);
            xuanzhuanzhou.Z = (p1.X * p2.Y - p2.X * p1.Y) / (p1.Y * p2.Z - p1.Z * p2.Y);
            xuanzhuanzhou.Normalize();
            zuoshou.Add(new Vector3d(list[0].X, list[0].Z, list[0].Y));
 
            double x11, x12, x13, x21, x22, x23, x31, x32, x33;
 
            Vector3d pos = new Vector3d();
            int iii = 1;
            for (int i = 0; i < 360; i++)
            {
                jiaodu = Math.PI * iii / 180;
                x11 = Math.Cos(jiaodu) + xuanzhuanzhou.X * xuanzhuanzhou.X * (1 - Math.Cos(jiaodu));
                x12 = xuanzhuanzhou.X * xuanzhuanzhou.Y * (1 - Math.Cos(jiaodu)) - xuanzhuanzhou.Z * Math.Sin(jiaodu);
                x13 = xuanzhuanzhou.X * xuanzhuanzhou.Z * (1 - Math.Cos(jiaodu)) + xuanzhuanzhou.Y * Math.Sin(jiaodu);
 
                x21 = xuanzhuanzhou.X * xuanzhuanzhou.Y * (1 - Math.Cos(jiaodu)) + xuanzhuanzhou.Z * Math.Sin(jiaodu);
                x22 = Math.Cos(jiaodu) + xuanzhuanzhou.Y * xuanzhuanzhou.Y * (1 - Math.Cos(jiaodu));
                x23 = xuanzhuanzhou.Y * xuanzhuanzhou.Z * (1 - Math.Cos(jiaodu)) - xuanzhuanzhou.X * Math.Sin(jiaodu);
 
                x31 = xuanzhuanzhou.X * xuanzhuanzhou.Z * (1 - Math.Cos(jiaodu)) - xuanzhuanzhou.Y * Math.Sin(jiaodu);
                x32 = xuanzhuanzhou.Y * xuanzhuanzhou.Z * (1 - Math.Cos(jiaodu)) + xuanzhuanzhou.X * Math.Sin(jiaodu);
                x33 = Math.Cos(jiaodu) + xuanzhuanzhou.Z * xuanzhuanzhou.Z * (1 - Math.Cos(jiaodu));
 
                double posX = zuoshou[0].X * x11 + zuoshou[0].Y * x21 + zuoshou[0].Z * x31;
                double posY = zuoshou[0].X * x12 + zuoshou[0].Y * x22 + zuoshou[0].Z * x32;
                double posZ = zuoshou[0].X * x13 + zuoshou[0].Y * x23 + zuoshou[0].Z * x33;
 
                zuoshou.Add(new Vector3d(posX, posY, posZ));
                iii++;
            }
            for (int i = 0; i < zuoshou.Count; i++)//将左手坐标系下点转换为世界坐标系下点坐标
            {
                shijiezuobiao.Add(new Vector3d(zuoshou[i].X, zuoshou[i].Z, zuoshou[i].Y));
            }
            for (int ii = 0; ii < shijiezuobiao.Count; ii++)//将世界坐标转换为经纬度坐标
            {
                jieguoweidu.Add(new Vector3d(ConvertWorldPositionToGeoPosition(shijiezuobiao[ii])));
            }
            for (int iiii = 0; iiii < jieguoweidu.Count; iiii++)//设置轨道圆的半径,值离地面高度
            {
                zuizhong.Add(new Vector3d(jieguoweidu[iiii].X, jieguoweidu[iiii].Y, 1000000));
            }
            return zuizhong;
        }

2、5.0版本

        /// </summary>
        /// 计算点对,返回结果保存经纬度
        /// </summary>
        /// <param name="list">旋转轴起始点世界坐标,两个点</param>
        /// <param name="Clist">中间需要旋转的点的世界坐标</param>
        /// <param name="jiaodu">旋转角度</param>
        /// <returns></returns>
        public static List<PointList> Translate(List<Vector3> listtt, List<Vector3> Clisttt, double jiaodu)
        {
            //将世界坐标转为左手坐标
            var list = new List<Vector3>();
            var Clist = new List<Vector3>();
            for (int i = 0; i < listtt.Count; i++)
            {
                list.Add(new Vector3(listtt.ElementAt(i).X, listtt.ElementAt(i).Z, listtt.ElementAt(i).Y));
            }
            for (int i = 0; i < Clisttt.Count; i++)
            {
                Clist.Add(new Vector3(Clisttt.ElementAt(i).X, Clisttt.ElementAt(i).Z, Clisttt.ElementAt(i).Y));
            }
 
            var LeftList = new List<PointList>();//存左手坐标系下的各点坐标
            var WorldList = new List<PointList>();//存世界坐标系下的各点坐标
            var LatLonList = new List<PointList>();//存世界坐标转换过来的经纬度坐标,弧度制
            var RetureList = new List<PointList>();//存返回坐标,经纬度,高
 
            Vector3 p1 = new Vector3(list[0].X, list[0].Y, list[0].Z);
            Vector3 p2 = new Vector3(list[1].X, list[1].Y, list[1].Z);
            Vector3 xuanzhuanzhou = new Vector3();
 
            double x11, x12, x13, x21, x22, x23, x31, x32, x33;
            double x111, x121, x131, x211, x221, x231, x311, x321, x331;
            jiaodu = System.Math.PI * jiaodu / 180;
            var jiaodu2 = -jiaodu;
 
            //CList最少存储2
            //if (Clist.Count == 1)
            //{
 
            //}
            for (int i = 0; i < Clist.Count; i++)
            {
                #region //确定旋转轴
                if (i == 0)
                {
                    xuanzhuanzhou.X = Clist.ElementAt(1).X - Clist.ElementAt(0).X;
                    xuanzhuanzhou.Y = Clist.ElementAt(1).Y - Clist.ElementAt(0).Y;
                    xuanzhuanzhou.Z = Clist.ElementAt(1).Z - Clist.ElementAt(0).Z;
                    var mo = System.Math.Sqrt(xuanzhuanzhou.X * xuanzhuanzhou.X + xuanzhuanzhou.Y * xuanzhuanzhou.Y + xuanzhuanzhou.Z * xuanzhuanzhou.Z);
                    xuanzhuanzhou.X = xuanzhuanzhou.X / mo;
                    xuanzhuanzhou.Y = xuanzhuanzhou.Y / mo;
                    xuanzhuanzhou.Z = xuanzhuanzhou.Z / mo;
                }
                else if (i == Clist.Count - 1)
                {
                    xuanzhuanzhou.X = Clist.ElementAt(Clist.Count - 2).X - Clist.ElementAt(Clist.Count - 1).X;
                    xuanzhuanzhou.Y = Clist.ElementAt(Clist.Count - 2).Y - Clist.ElementAt(Clist.Count - 1).Y;
                    xuanzhuanzhou.Z = Clist.ElementAt(Clist.Count - 2).Z - Clist.ElementAt(Clist.Count - 1).Z;
                    var mo = System.Math.Sqrt(xuanzhuanzhou.X * xuanzhuanzhou.X + xuanzhuanzhou.Y * xuanzhuanzhou.Y + xuanzhuanzhou.Z * xuanzhuanzhou.Z);
                    xuanzhuanzhou.X = xuanzhuanzhou.X / mo;
                    xuanzhuanzhou.Y = xuanzhuanzhou.Y / mo;
                    xuanzhuanzhou.Z = xuanzhuanzhou.Z / mo;
                }
                else
                {
                    xuanzhuanzhou.X = Clist.ElementAt(i - 1).X - Clist.ElementAt(i + 1).X;
                    xuanzhuanzhou.Y = Clist.ElementAt(i - 1).Y - Clist.ElementAt(i + 1).Y;
                    xuanzhuanzhou.Z = Clist.ElementAt(i - 1).Z - Clist.ElementAt(i + 1).Z;
                    var mo = System.Math.Sqrt(xuanzhuanzhou.X * xuanzhuanzhou.X + xuanzhuanzhou.Y * xuanzhuanzhou.Y + xuanzhuanzhou.Z * xuanzhuanzhou.Z);
                    xuanzhuanzhou.X = xuanzhuanzhou.X / mo;
                    xuanzhuanzhou.Y = xuanzhuanzhou.Y / mo;
                    xuanzhuanzhou.Z = xuanzhuanzhou.Z / mo;
                }
 
                #endregion
                #region 坐标计算
                Vector3 pos = new Vector3();
                x11 = System.Math.Cos(jiaodu) + xuanzhuanzhou.X * xuanzhuanzhou.X * (1 - System.Math.Cos(jiaodu));
                x12 = xuanzhuanzhou.X * xuanzhuanzhou.Y * (1 - System.Math.Cos(jiaodu)) - xuanzhuanzhou.Z * System.Math.Sin(jiaodu);
                x13 = xuanzhuanzhou.X * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu)) + xuanzhuanzhou.Y * System.Math.Sin(jiaodu);
                x21 = xuanzhuanzhou.X * xuanzhuanzhou.Y * (1 - System.Math.Cos(jiaodu)) + xuanzhuanzhou.Z * System.Math.Sin(jiaodu);
                x22 = System.Math.Cos(jiaodu) + xuanzhuanzhou.Y * xuanzhuanzhou.Y * (1 - System.Math.Cos(jiaodu));
                x23 = xuanzhuanzhou.Y * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu)) - xuanzhuanzhou.X * System.Math.Sin(jiaodu);
                x31 = xuanzhuanzhou.X * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu)) - xuanzhuanzhou.Y * System.Math.Sin(jiaodu);
                x32 = xuanzhuanzhou.Y * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu)) + xuanzhuanzhou.X * System.Math.Sin(jiaodu);
                x33 = System.Math.Cos(jiaodu) + xuanzhuanzhou.Z * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu));
                double posX = Clist.ElementAt(i).X * x11 + Clist.ElementAt(i).Y * x21 + Clist.ElementAt(i).Z * x31;
                double posY = Clist.ElementAt(i).X * x12 + Clist.ElementAt(i).Y * x22 + Clist.ElementAt(i).Z * x32;
                double posZ = Clist.ElementAt(i).X * x13 + Clist.ElementAt(i).Y * x23 + Clist.ElementAt(i).Z * x33;
 
                x111 = System.Math.Cos(jiaodu2) + xuanzhuanzhou.X * xuanzhuanzhou.X * (1 - System.Math.Cos(jiaodu2));
                x121 = xuanzhuanzhou.X * xuanzhuanzhou.Y * (1 - System.Math.Cos(jiaodu2)) - xuanzhuanzhou.Z * System.Math.Sin(jiaodu2);
                x131 = xuanzhuanzhou.X * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu2)) + xuanzhuanzhou.Y * System.Math.Sin(jiaodu2);
                x211 = xuanzhuanzhou.X * xuanzhuanzhou.Y * (1 - System.Math.Cos(jiaodu2)) + xuanzhuanzhou.Z * System.Math.Sin(jiaodu2);
                x221 = System.Math.Cos(jiaodu2) + xuanzhuanzhou.Y * xuanzhuanzhou.Y * (1 - System.Math.Cos(jiaodu2));
                x231 = xuanzhuanzhou.Y * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu2)) - xuanzhuanzhou.X * System.Math.Sin(jiaodu2);
                x311 = xuanzhuanzhou.X * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu2)) - xuanzhuanzhou.Y * System.Math.Sin(jiaodu2);
                x321 = xuanzhuanzhou.Y * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu2)) + xuanzhuanzhou.X * System.Math.Sin(jiaodu2);
                x331 = System.Math.Cos(jiaodu2) + xuanzhuanzhou.Z * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu2));
                double posX1 = Clist.ElementAt(i).X * x111 + Clist.ElementAt(i).Y * x211 + Clist.ElementAt(i).Z * x311;
                double posY1 = Clist.ElementAt(i).X * x121 + Clist.ElementAt(i).Y * x221 + Clist.ElementAt(i).Z * x321;
                double posZ1 = Clist.ElementAt(i).X * x131 + Clist.ElementAt(i).Y * x231 + Clist.ElementAt(i).Z * x331;
                #endregion
 
                if(i==0)
                { LeftList.Add(new PointList { StartPoint = new Vector3(posX1, posY1, posZ1), EndPoint = new Vector3(posX, posY, posZ) }); }
                else
                { LeftList.Add(new PointList { StartPoint = new Vector3(posX, posY, posZ), EndPoint = new Vector3(posX1, posY1, posZ1) }); }
               
            }
 
            #region 坐标变换
            //将左手坐标系下点转换为世界坐标系下点坐标
            for (int i = 0; i < LeftList.Count; i++)
            {
                WorldList.Add(new PointList
                {
                    StartPoint = new Vector3(LeftList.ElementAt(i).StartPoint.X, LeftList.ElementAt(i).StartPoint.Z, LeftList.ElementAt(i).StartPoint.Y),
                    EndPoint = new Vector3(LeftList.ElementAt(i).EndPoint.X, LeftList.ElementAt(i).EndPoint.Z, LeftList.ElementAt(i).EndPoint.Y)
                });
            }
 
            // 将世界坐标转换为经纬度坐标
            for (int i = 0; i < WorldList.Count; i++)
            {
                var TempStart = new Vector3();
                var TempEnd = new Vector3();
                TempStart = SpatialCalculator.CartesianToSpherical(WorldList.ElementAt(i).StartPoint);
                TempEnd = SpatialCalculator.CartesianToSpherical(WorldList.ElementAt(i).EndPoint);
                LatLonList.Add(new PointList { StartPoint = TempStart, EndPoint = TempEnd });
            }
 
 
            //将弧度转换为度,并调整存储位置
            for (int i = 0; i < LatLonList.Count; i++)
            {
                var TempStart = new Vector3();
                var TempEnd = new Vector3();
 
                ///LatLonList里面,X,Y,Z分别存储的是高,纬度,经度.绘制数据源里面的点需要经纬高,这里需要重新变换赋值。
                TempStart.X = (LatLonList.ElementAt(i).StartPoint.Z * 180) / System.Math.PI;
                TempStart.Y = (LatLonList.ElementAt(i).StartPoint.Y * 180) / System.Math.PI;
                TempStart.Z = LatLonList.ElementAt(i).StartPoint.X - 6378137;
                TempEnd.X = (LatLonList.ElementAt(i).EndPoint.Z * 180) / System.Math.PI;
                TempEnd.Y = (LatLonList.ElementAt(i).EndPoint.Y * 180) / System.Math.PI;
                TempEnd.Z = LatLonList.ElementAt(i).EndPoint.X - 6378137;
 
                TempStart.Z = listenaltitude.GetAltitude(TempStart.Y, TempStart.X);
                TempEnd.Z = listenaltitude.GetAltitude(TempEnd.Y, TempEnd.X);
 
                RetureList.Add(new PointList { StartPoint = TempStart, EndPoint = TempEnd });
 
            }
 
            LeftList.Clear();
            WorldList.Clear();
            LatLonList.Clear();
            #endregion
            return RetureList;
        }
         

 


以上是关于定点绕定轴旋转的主要内容,如果未能解决你的问题,请参考以下文章

unity 如何让物体绕自己的中心轴转

iOS 使用transform和CABasicAnimation实现视图围绕定点旋转和实现一个旋转的圆的动画 以转盘为例

css怎么设置图片定点旋转?

从当前位置围绕固定点旋转

处理屏幕旋转上的片段重复(带有示例代码)

使用 ActionBar 旋转 Android 的双片段