• [RGEOS]数学基础


    1.向量Vector3d

      1 using System;
      2 
      3 namespace RGeos.Geometry
      4 {
      5     /// <summary>
      6     /// 3D向量类
      7     /// </summary>
      8     public class Vector3d
      9     {
     10         public double[] vector;
     11         private const double E = 0.0000001f;
     12         /// <summary>
     13         /// 
     14         /// </summary>
     15         /// <param name="x"></param>
     16         /// <param name="y"></param>
     17         /// <param name="z"></param>
     18         /// 
     19         public Vector3d()
     20         {
     21             vector = new double[3];
     22         }
     23         public Vector3d(double x, double y, double z)
     24         {
     25             vector = new double[3] { x, y, z };
     26         }
     27         public Vector3d(Vector3d vct)
     28         {
     29             vector = new double[3];
     30             vector[0] = vct.X;
     31             vector[1] = vct.Y;
     32             vector[2] = vct.Z;
     33         }
     34         #region 属性
     35         /// <summary>
     36         /// X向量
     37         /// </summary>
     38         public double X
     39         {
     40             get { return vector[0]; }
     41             set { vector[0] = value; }
     42         }
     43         /// <summary>
     44         /// Y向量
     45         /// </summary>
     46         public double Y
     47         {
     48             get { return vector[1]; }
     49             set { vector[1] = value; }
     50         }
     51         /// <summary>
     52         /// Z向量
     53         /// </summary>
     54         public double Z
     55         {
     56             get { return vector[2]; }
     57             set { vector[2] = value; }
     58         }
     59         #endregion
     60 
     61         #region 向量操作
     62         /// <summary>
     63         /// /// <summary>
     64         /// 向量加法+
     65         /// </summary>
     66         /// <param name="lhs"></param>
     67         /// <param name="rhs"></param>
     68         /// <returns></returns>
     69         public static Vector3d operator +(Vector3d lhs, Vector3d rhs)//向量加
     70         {
     71             Vector3d result = new Vector3d(lhs);
     72             result.X += rhs.X;
     73             result.Y += rhs.Y;
     74             result.Z += rhs.Z;
     75             return result;
     76         }
     77         /// <summary>
     78         /// 向量减-
     79         /// </summary>
     80         /// <param name="lhs"></param>
     81         /// <param name="rhs"></param>
     82         /// <returns></returns>
     83         public static Vector3d operator -(Vector3d lhs, Vector3d rhs)//向量减法
     84         {
     85             Vector3d result = new Vector3d(lhs);
     86             result.X -= rhs.X;
     87             result.Y -= rhs.Y;
     88             result.Z -= rhs.Z;
     89             return result;
     90         }
     91         /// <summary>
     92         /// 向量除
     93         /// </summary>
     94         /// <param name="lhs"></param>
     95         /// <param name="rhs"></param>
     96         /// <returns></returns>
     97         public static Vector3d operator /(Vector3d lhs, double rhs)//向量除以数量
     98         {
     99             if (rhs != 0)
    100                 return new Vector3d(lhs.X / rhs, lhs.Y / rhs, lhs.Z / rhs);
    101             else
    102                 return new Vector3d(0, 0, 0);
    103         }
    104         /// <summary>
    105         /// 向量数乘*
    106         /// </summary>
    107         /// <param name="lhs"></param>
    108         /// <param name="rhs"></param>
    109         /// <returns></returns>
    110         public static Vector3d operator *(double lhs, Vector3d rhs)//左乘数量
    111         {
    112             return new Vector3d(lhs * rhs.X, lhs * rhs.Y, lhs * rhs.Z);
    113         }
    114         /// <summary>
    115         /// 向量数乘
    116         /// </summary>
    117         /// <param name="lhs"></param>
    118         /// <param name="rhs"></param>
    119         /// <returns></returns>
    120         public static Vector3d operator *(Vector3d lhs, double rhs)//右乘数量
    121         {
    122             return new Vector3d(lhs.X * rhs, lhs.Y * rhs, lhs.Z * rhs);
    123         }
    124 
    125         /// <summary>
    126         /// 判断量向量是否相等
    127         /// </summary>
    128         /// <param name="lhs"></param>
    129         /// <param name="rhs"></param>
    130         /// <returns>True 或False</returns>
    131         public static bool operator ==(Vector3d lhs, Vector3d rhs)
    132         {
    133             if (Math.Abs(lhs.X - rhs.X) < E && Math.Abs(lhs.Y - rhs.Y) < E && Math.Abs(lhs.Z - rhs.Z) < E)
    134                 return true;
    135             else
    136                 return false;
    137         }
    138         public static bool operator !=(Vector3d lhs, Vector3d rhs)
    139         {
    140             return !(lhs == rhs);
    141         }
    142         public override bool Equals(object obj)
    143         {
    144             return base.Equals(obj);
    145         }
    146         public override int GetHashCode()
    147         {
    148             return base.GetHashCode();
    149         }
    150         public override string ToString()
    151         {
    152             return "(" + X + "," + Y + "," + Z + ")";
    153         }
    154         /// <summary>
    155         /// 向量叉积,求与两向量垂直的向量
    156         /// </summary>
    157         public static Vector3d Cross(Vector3d v1, Vector3d v2)
    158         {
    159             Vector3d r = new Vector3d(0, 0, 0);
    160             r.X = (v1.Y * v2.Z) - (v1.Z * v2.Y);
    161             r.Y = (v1.Z * v2.X) - (v1.X * v2.Z);
    162             r.Z = (v1.X * v2.Y) - (v1.Y * v2.X);
    163             return r;
    164         }
    165         /// <summary>
    166         /// 向量数量积
    167         /// </summary>
    168         /// <param name="lhs"></param>
    169         /// <param name="rhs"></param>
    170         /// <returns></returns>
    171         public static double operator *(Vector3d lhs, Vector3d rhs)//
    172         {
    173             return lhs.X * rhs.X + lhs.Y * rhs.Y + lhs.Z * rhs.Z;
    174         }
    175         /// <summary>
    176         /// 内积
    177         /// </summary>
    178         /// <param name="v1"></param>
    179         /// <param name="v2"></param>
    180         /// <returns></returns>
    181         public static double InnerMultiply(Vector3d v1, Vector3d v2)
    182         {
    183             double inner = 0.0;
    184             inner = v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z;
    185             return inner;
    186         }
    187         /// <summary>
    188         /// 求向量长度,向量的模
    189         /// </summary>
    190         public static double Magnitude(Vector3d v1)
    191         {
    192             return (double)Math.Sqrt((v1.X * v1.X) + (v1.Y * v1.Y) + (v1.Z * v1.Z));
    193         }
    194         /// <summary>
    195         /// 单位化向量
    196         /// </summary>
    197         public static Vector3d Normalize(Vector3d v1)
    198         {
    199             double magnitude = Magnitude(v1);
    200             v1 = v1 / magnitude;
    201             return v1;
    202         }
    203         #endregion
    204     }
    205 }
    View Code

    2. 计算基础

      1 using System;
      2 using RGeos.Geometry;
      3 
      4 namespace RGeos.Basic
      5 {
      6     public class RMath
      7     {
      8         public static double SMALL_NUM = 0.0000000001; // anything that avoids division overflow
      9         /// <summary>
     10         ///  dot product (3D) which allows vector operations in arguments
     11         /// </summary>
     12         /// <param name="u"></param>
     13         /// <param name="v"></param>
     14         /// <returns></returns>
     15         public static double dot(Vector3d u, Vector3d v)
     16         {
     17             return ((u).X * (v).X + (u).Y * (v).Y + (u).Z * (v).Z);
     18         }
     19         /// <summary>
     20         /// 2D数量积,点乘
     21         /// </summary>
     22         /// <param name="u"></param>
     23         /// <param name="v"></param>
     24         /// <returns></returns>
     25         public static double dot2(Vector3d u, Vector3d v)
     26         {
     27             return ((u).X * (v).X + (u).Y * (v).Y);
     28         }
     29         /// <summary>
     30         /// 2D矢量叉积,定义为(0,0),P1,P2和P1P2包围四边形的带符号面积
     31         /// </summary>
     32         /// <param name="u"></param>
     33         /// <param name="v"></param>
     34         /// <returns></returns>
     35         public static double perp(Vector3d u, Vector3d v)
     36         {
     37             return ((u).X * (v).Y - (u).Y * (v).X);
     38         }
     39         /// <summary>
     40         /// 向量的模
     41         /// </summary>
     42         /// <param name="v"></param>
     43         /// <returns></returns>
     44         public static double norm(Vector3d v)
     45         {
     46             return Math.Sqrt(dot(v, v));  // norm = length of vector
     47         }
     48         /// <summary>
     49         /// 两点间距离
     50         /// </summary>
     51         /// <param name="u"></param>
     52         /// <param name="v"></param>
     53         /// <returns></returns>
     54         public static double d(Vector3d u, Vector3d v)
     55         {
     56             return norm(u - v);       // distance = norm of difference
     57         }
     58 
     59         public static double d(RPoint P1, RPoint P2)
     60         {
     61             return GetDistance(P1, P2);       // distance = norm of difference
     62         }
     63 
     64         // 判断点P2在直线P0P1的左边还是在右边,还是在直线上
     65         //isLeft(): tests if a point is Left|On|Right of an infinite line.
     66         //    Input:  three points P0, P1, and P2
     67         //    Return: >0 for P2 left of the line through P0 and P1
     68         //            =0 for P2 on the line
     69         //            <0 for P2 right of the line
     70         public static int isLeft(RPoint P0, RPoint P1, RPoint P2)
     71         {
     72             double l = ((P1.X - P0.X) * (P2.Y - P0.Y) - (P2.X - P0.X) * (P1.Y - P0.Y));
     73             return (int)l;
     74         }
     75         /// <summary>
     76         /// 获取由两个点所形成的向量的象限角度
     77         /// </summary>
     78         /// <param name="preCoord">第一个点的坐标</param>
     79         /// <param name="nextCoord">第二个点的坐标</param>
     80         /// <returns></returns>
     81         public static double GetQuadrantAngle(RPoint preCoord, RPoint nextCoord)
     82         {
     83             return GetQuadrantAngle(nextCoord.X - preCoord.X, nextCoord.Y - preCoord.Y);
     84         }
     85         /// <summary>
     86         /// 由增量X和增量Y所形成的向量的象限角度
     87         /// 区别方位角:方位角以正北方向顺时针
     88         /// |                    |
     89         /// |  /                 |b /
     90         /// | / a                |^/
     91         /// |/_)____象限角       |/______方位角
     92         /// </summary>
     93         /// <param name="x">增量X</param>
     94         /// <param name="y">增量Y</param>
     95         /// <returns>象限角</returns>
     96         public static double GetQuadrantAngle(double x, double y)
     97         {
     98             double theta = Math.Atan(y / x);
     99             if (x > 0 && y == 0) return 0;
    100             if (x == 0 && y > 0) return Math.PI / 2;
    101             if (x < 0 && y == 0) return Math.PI;
    102             if (x == 0 && y < 0) return 3 * Math.PI / 2;
    103 
    104             if (x > 0 && y > 0) return theta;
    105             if (x > 0 && y < 0) return Math.PI * 2 + theta;
    106             if (x < 0 && y > 0) return theta + Math.PI;
    107             if (x < 0 && y < 0) return theta + Math.PI;
    108             return theta;
    109         }
    110         /// <summary>
    111         /// 获取由相邻的三个点A-B-C所形成的两个向量之间的夹角
    112         /// 向量AB,BC形成的夹角
    113         /// </summary>
    114         /// <param name="preCoord">第一个点</param>
    115         /// <param name="midCoord">中间点</param>
    116         /// <param name="nextCoord">第三个点</param>
    117         /// <returns></returns>
    118         public static double GetIncludedAngle(RPoint preCoord, RPoint midCoord, RPoint nextCoord)
    119         {
    120             double innerProduct = (midCoord.X - preCoord.X) * (nextCoord.X - midCoord.X) + (midCoord.Y - preCoord.Y) * (nextCoord.Y - midCoord.Y);
    121             double mode1 = Math.Sqrt(Math.Pow((midCoord.X - preCoord.X), 2.0) + Math.Pow((midCoord.Y - preCoord.Y), 2.0));
    122             double mode2 = Math.Sqrt(Math.Pow((nextCoord.X - midCoord.X), 2.0) + Math.Pow((nextCoord.Y - midCoord.Y), 2.0));
    123             return Math.Acos(innerProduct / (mode1 * mode2));
    124         }
    125         /// <summary>
    126         /// 获取由两个点所形成的向量的模(长度)
    127         /// </summary>
    128         /// <param name="preCoord">第一个点</param>
    129         /// <param name="nextCoord">第二个点</param>
    130         /// <returns>由两个点所形成的向量的模(长度)</returns>
    131         public static double GetDistance(RPoint preCoord, RPoint nextCoord)
    132         {
    133             return Math.Sqrt(Math.Pow((nextCoord.X - preCoord.X), 2) + Math.Pow((nextCoord.Y - preCoord.Y), 2));
    134         }
    135     }
    136 }
    RMath
  • 相关阅读:
    第二十二章 6未命名的命名空间 简单
    第二十二章 4使用关键字using 简单
    第二十三模板 3具体化函数模板 简单
    第二十二章 2创建命名空间 简单
    第二十三模板 7复杂类模板 简单
    第二十二章 3使用命名空间 简单
    第二十二章 1什么是命名空间 简单
    第二十三模板 2重载模板 简单
    第二十三模板 1什么是模板 简单
    测定事务引擎设计的基准
  • 原文地址:https://www.cnblogs.com/yhlx125/p/3438857.html
Copyright © 2020-2023  润新知