热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C#矩阵预算和一些基本的几何运算

以前工作中写的,这里备个份,有可能用到基本的矩阵运算类,测试20阶以内应该没啥问题,超过20阶不好使。。。一些

以前工作中写的,这里备个份,有可能用到

基本的矩阵运算类,测试20阶以内应该没啥问题,超过20阶不好使。。。

 /// 
    /// 矩阵   异常 512索引 1024无解 2046矩阵行列 
    /// 
    public class Matrix
    {
        private int m_row;//
        private int m_col;//
        private double[,] m_data;//数据
        /// 元素
        /// 
        /// 
        /// 
        /// 
        public double this[int ro, int co]
        {
            get
            {
                if (ro >= m_row || co >= m_col || ro <0 || co <0) throw new Exception("512");
                return m_data[ro, co];
            }
            set
            {
                if (ro >= m_row || co >= m_col || ro <0 || co <0) throw new Exception("512");
                m_data[ro, co] = value;
            }
        }
        /// 行数
        /// 
        public int Row
        { get { return m_row; } }
        /// 列数
        /// 
        public int Column
        { get { return m_col; } }
        public Matrix()
        { m_row = 0; m_col = 0; m_data = new double[0, 0]; }
        public Matrix(double[,] matrix)
        {
            m_row = matrix.GetLength(0);
            m_col = matrix.GetLength(1);
            m_data = matrix;
        }
        public Matrix(int ro, int co)
        {
            if (ro <0 || co <0) throw new Exception("512");
            m_row = ro;
            m_col = co;
            m_data = new double[ro, co];
        }
        public static Matrix operator *(Matrix left, Matrix right)
        {
            if (left.Column != right.Row) throw new Exception("2046");
            Matrix re = new Matrix(left.Row, right.Column);
            for (int i = 0; i )
            {
                for (int j = 0; j )
                {
                    for (int k = 0; k )
                    {
                        re[i, j] += left[i, k] * right[k, j];
                    }
                }
            }
            return re;

        }
        public static Matrix operator +(Matrix left, Matrix right)
        {
            if (left.Row != right.Row || left.Column != right.Column)
                throw new Exception("2046");
            Matrix re = new Matrix(left.Row, left.Column);
            for (int i = 0; i )
            {
                for (int j = 0; j )
                {
                    re[i, j] = left[i, j] + right[i, j];
                }
            }
            return re;
        }
        public static Matrix operator -(Matrix left, Matrix right)
        {
            if (left.Row != right.Row || left.Column != right.Column)
                throw new Exception("2046");
            Matrix re = new Matrix(left.Row, left.Column);
            for (int i = 0; i )
            {
                for (int j = 0; j )
                {
                    re[i, j] = left[i, j] - right[i, j];
                }
            }
            return re;
        }
        public static Matrix operator *(double factor, Matrix right)
        {
            Matrix re = new Matrix(right.Row, right.Column);
            for (int i = 0; i )
            {
                for (int j = 0; j )
                {
                    re[i, j] = right[i, j] * factor;
                }
            }
            return re;
        }
        public static Matrix operator *(Matrix left, double factor)
        {
            return factor * left;
        }
        /// 转置
        /// 
        /// 
        public Matrix Matrixtran()
        {
            Matrix re = new Matrix(this.m_col, this.m_row);
            for (int i = 0; i <this.m_row; i++)
            {
                for (int j = 0; j <this.m_col; j++)
                {
                    re[j, i] = this[i, j];
                }
            }
            return re;
        }
        /// 行列式        //加边法
        /// 
        /// 
        /// 
        public double Matrixvalue()
        {
            if (this.m_row != this.m_col)
            { throw new Exception("2046"); }
            int n = this.m_row;
            if (n == 2) return this[0, 0] * this[1, 1] - this[0, 1] * this[1, 0];
            double dsum = 0, dSign = 1;
            for (int i = 0; i )
            {
                Matrix tempa = new Matrix(n - 1, n - 1);
                for (int j = 0; j 1; j++)
                {
                    for (int k = 0; k 1; k++)
                    {
                        tempa[j, k] = this[j + 1, k >= i ? k + 1 : k];
                    }
                }
                dsum += this[0, i] * dSign * tempa.Matrixvalue();
                dSign = dSign * -1;
            }
            return dsum;
        }
        /// 求逆
        /// 
        /// 
        /// 
        public Matrix InverseMatrix()
        {
            int row = this.m_row; int col = this.m_col;
            if (row != col) throw new Exception("2046");
            Matrix re = new Matrix(row, col);
            double val = this.Matrixvalue();
            if (Math.Abs(val) <= 1E-6) { throw new Exception("1024"); }
            re = this.AdjointMatrix();
            for (int i = 0; i )
            {
                for (int j = 0; j )
                {
                    re[i, j] = re[i, j] / val;
                }
            }
            return re;

        }
        /// 求伴随矩阵
        /// 
        /// 
        /// 
        public Matrix AdjointMatrix()
        {
            int row = this.m_row;
            Matrix re = new Matrix(row, row);
            for (int i = 0; i )
            {
                for (int j = 0; j )
                {
                    Matrix temp = new Matrix(row - 1, row - 1);
                    for (int x = 0; x 1; x++)
                    {
                        for (int y = 0; y 1; y++)
                        {
                            temp[x, y] = this[x 1, y 1];
                        }
                    }
                    re[j, i] = ((i + j) % 2 == 0 ? 1 : -1) * temp.Matrixvalue();
                }
            }
            return re;
        }
    }

一些基本的几何运算

 public class CalcCls
    {

        /// 
        /// 根据两点计算距离两点连线为R的两点,默认垂足为A
        /// 
        /// A 已知点
        /// B 已知点
        /// 距离
        /// C 待求点
        /// D 待求点
        /// AB两点重合返回false 正常为true
        protected bool Vertical(PointXY pointa, PointXY pointb, double R,
            ref PointXY pointc, ref PointXY pointd)
        {
            try
            {
                //(X-xa)^2+(Y-ya)^2=R*R    距离公式
                //(X-xa)*(xb-xa)+(Y-ya)*(yb-ya)=0   垂直
                //解方程得两点即为所求点
                pointc.X = pointa.X - (pointb.Y - pointa.Y) * R / Distance(pointa, pointb);
                pointc.Y = pointa.Y + (pointb.X - pointa.X) * R / Distance(pointa, pointb);

                pointd.X = pointa.X + (pointb.Y - pointa.Y) * R / Distance(pointa, pointb);
                pointd.Y = pointa.Y - (pointb.X - pointa.X) * R / Distance(pointa, pointb);

                return true;
            }
            catch
            {
                //如果A,B两点重合会报错,那样就返回false
                return false;
            }
        }
        ///  判断pt在pa到pb的左侧
        /// 
        protected bool IsLeft(PointXY pa, PointXY pb, PointXY pt)
        {
            //ax+by+c=0
            double a = pb.Y - pa.Y;
            double b = pa.X - pb.X;
            double c = pb.X * pa.Y - pa.X * pb.Y;
            double d = a * pt.X + b * pt.Y + c;
            if (d <0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        ///  计算P1P2和P3P4两条线段所在直线的交点
        /// 如果两条线段在同一直线,返回较短的线段的端点,p2或P3
        /// 输出交点
        /// 有交点返回true 否则返回false
        protected void calcIntersectionPoint(PointXY pt1, PointXY pt2, PointXY pt3, PointXY pt4, ref PointXY pt)
        {   //ax+by=c
            double a1, b1, c1, a2, b2, c2;
            a1 = pt1.Y - pt2.Y;
            b1 = pt2.X - pt1.X;
            c1 = pt1.Y * pt2.X - pt2.Y * pt1.X;

            a2 = pt3.Y - pt4.Y;
            b2 = pt4.X - pt3.X;
            c2 = pt3.Y * pt4.X - pt4.Y * pt3.X;
            double db = a1 * b2 - a2 * b1;
            if (db == 0)//平行或共线
            {
                if (a1 * pt3.X + b1 * pt3.Y == c1)//共线
                {
                    pt = (Distance(pt1, pt2) > Distance(pt3, pt4)) ? pt3 : pt2;
                }
            }
            else
            {
                pt.X = (b2 * c1 - b1 * c2) / db;
                pt.Y = (a1 * c2 - a2 * c1) / db;
            }
        }
        /// 判断P1P2和P3P4线段是否相交
        protected bool IsIntersect(PointXY pt1, PointXY pt2, PointXY pt3, PointXY pt4)
        {
            //return ((max(u.s.x, u.e.x) >= min(v.s.x, v.e.x)) && //排斥实验 
            //(max(v.s.x, v.e.x) >= min(u.s.x, u.e.x)) &&
            //(max(u.s.y, u.e.y) >= min(v.s.y, v.e.y)) &&
            //(max(v.s.y, v.e.y) >= min(u.s.y, u.e.y)) &&
            //(multiply(v.s, u.e, u.s) * multiply(u.e, v.e, u.s) >= 0) && //跨立实验 
            //(multiply(u.s, v.e, v.s) * multiply(v.e, u.e, v.s) >= 0)); 
            //判断矩形是否相交
            if (Math.Max(pt1.X, pt2.X) >= Math.Min(pt3.X, pt4.X) &&
                Math.Max(pt3.X, pt4.X) >= Math.Min(pt3.X, pt4.X) &&
                Math.Max(pt1.Y, pt2.Y) >= Math.Min(pt3.Y, pt4.Y) &&
                Math.Max(pt3.Y, pt4.Y) >= Math.Min(pt1.Y, pt2.Y))
            {
                //线段跨立
                if (multiply(pt3, pt2, pt1) * multiply(pt2, pt4, pt1) >= 0 &&
                    multiply(pt1, pt4, pt3) * multiply(pt4, pt2, pt3) >= 0)
                {
                    return true;
                }

            }
            return false;
        }
        /****************************************************************************** 
        r=multiply(sp,ep,op),得到(sp-op)*(ep-op)的叉积 
        r>0:ep在矢量opsp的逆时针方向; 
        r=0:opspep三点共线; 
        r<0:ep在矢量opsp的顺时针方向 
        *******************************************************************************/
        ///  计算p1p0和p2p0叉积 
        /// 
        protected double multiply(PointXY pt1, PointXY pt2, PointXY p0)
        {
            //return ((sp.x - op.x) * (ep.y - op.y) - (ep.x - op.x) * (sp.y - op.y)); 
            double mult = (pt1.X - p0.X) * (pt2.Y - p0.Y) - (pt2.X - p0.X) * (pt1.Y - p0.Y);
            return mult;

        }
        /// 按照距离将交点排序 
        /// 
        /// 起点
        /// 
        protected PointXY[] sortPoint(PointXY[] temline, PointXY ps)
        {
            List lp = new List();
            List sortlp = new List();
            lp.AddRange(temline);
            if (temline.Length <1) return sortlp.ToArray();
            for (; lp.Count > 1; )
            {
                PointXY pd = lp[0];
                for (int i = 0; i 1; i++)
                {
                    if (Distance(ps, pd) > Distance(ps, lp[i + 1]))
                    {
                        pd = lp[i + 1];
                    }
                }
                lp.Remove(pd);
                sortlp.Add(pd);
            }
            sortlp.Add(lp[0]);
            return sortlp.ToArray();
        }

        /// 
        /// 根据两点计算两点连线上距离A点L的点 输出C点为距离B近的点上的点 D为距离B远的点
        /// 
        /// A点 默认为计算距离A点L的点
        /// B点
        /// 距离
        /// 返回点C
        /// 返回点D 有时候没用
        /// 
        protected bool GapP(PointXY pointa, PointXY pointb, double L, ref PointXY pointc, ref PointXY pointd)
        {
            try
            {
                PointXY pc = new PointXY();
                PointXY pd = new PointXY();
                //(north-xa)^2+(east-ya)^2=L    两点距离公式
                //(north-xa)*(ya-yb)-(east-ya)(xa-xb)=0   直线平行条件,注意,是CA和AB平行(实际是C点在AB上)
                pc.X = pointa.X +
                    (pointa.X - pointb.X) * L / Distance(pointa, pointb);
                pc.Y = pointa.Y +
                    (pointa.Y - pointb.Y) * L / Distance(pointa, pointb);

                pd.X = pointa.X -
                    (pointa.X - pointb.X) * L / Distance(pointa, pointb);
                pd.Y = pointa.Y -
                    (pointa.Y - pointb.Y) * L / Distance(pointa, pointb);

                pointc = Distance(pc, pointb) > Distance(pd, pointb) ? pd : pc; //取距离B近的点
                pointd = Distance(pc, pointb) > Distance(pd, pointb) ? pc : pd;//取距离B远的点

                return true;
            }
            catch
            {
                //如果A,B两点重合会报错,那样就返回false
                return false;
            }
        }

        ///  返回两点的距离 
        /// 
        /// 
        /// 
        public double Distance(double xa, double ya, double xb, double yb)
        {
            double L;
            L = Math.Sqrt(Math.Pow(xa - xb, 2) + Math.Pow(ya - yb, 2));
            return L;
        }
        public double Distance(PointXY pa, PointXY pb)
        {
            return Distance(pa.X, pa.Y, pb.X, pb.Y);
        }

        ///  用VS自带算法判断点是否在区域内 
        /// 
        /// 
        /// 
        public bool PtInPolygon(PointXY pd, PointXY[] pdsArray)
        {
            PointF pt = new PointF();
            pt.X = (float)pd.X;
            pt.Y = (float)pd.Y;
            List pl = new List();
            for (int i = 0; i )
            {
                Point p = new Point();
                p.X = (int)pdsArray[i].X;
                p.Y = (int)pdsArray[i].Y;
                pl.Add(p);
            }
            if (pl.Count <3) return false;
            using (System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath())
            {
                gp.AddPolygon(pl.ToArray());
                return gp.IsVisible(pt);
            }
        }

        /// 
        /// 求线段的方位角0-360
        /// 
        /// 线段起点
        /// 线段终点
        /// 从0度顺时针偏转到该线段所划过的角度
        protected double Angle(PointXY pa, PointXY pb)
        {
            double Ang = 0;
            double a;
            try
            {
                a = Math.Acos((pb.X - pa.X) / Distance(pa, pb));

                if (pb.Y - pa.Y <0)
                {
                    a = 2 * Math.PI - a;
                }
                Ang = a * 180d / Math.PI;
                return Ang;
            }
            catch
            {
                Ang = 0;
                return Ang;
            }
        }

        /// 角度到弧度
        /// 
        /// 
        private double AngleToRadian(double value)
        {
            return value * Math.PI / 180d;
        }

        ///  弧度到角度
        /// 
        /// 
        private double RadianToAngle(double value)
        {
            return value * 180d / Math.PI;
        }

    }

    public struct PointXY
    {
        public double Y;
        public double X;
 
    }

C# 矩阵预算和一些基本的几何运算


推荐阅读
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 生成对抗式网络GAN及其衍生CGAN、DCGAN、WGAN、LSGAN、BEGAN介绍
    一、GAN原理介绍学习GAN的第一篇论文当然由是IanGoodfellow于2014年发表的GenerativeAdversarialNetworks(论文下载链接arxiv:[h ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
author-avatar
黑m泽猫咪2009
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有