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

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

 /// <summary>
/// 矩阵 异常 512索引 1024无解 2046矩阵行列
/// </summary>
public class Matrix
{
private int m_row;//行
private int m_col;//列
private double[,] m_data;//数据
/// <summary>元素
/// </summary>
/// <param name="ro"></param>
/// <param name="co"></param>
/// <returns></returns>
public double this[int ro, int co]
{
get
{
if (ro >= m_row || co >= m_col || ro < || co < ) throw new Exception("");
return m_data[ro, co];
}
set
{
if (ro >= m_row || co >= m_col || ro < || co < ) throw new Exception("");
m_data[ro, co] = value;
}
}
/// <summary>行数
/// </summary>
public int Row
{ get { return m_row; } }
/// <summary>列数
/// </summary>
public int Column
{ get { return m_col; } }
public Matrix()
{ m_row = ; m_col = ; m_data = new double[, ]; }
public Matrix(double[,] matrix)
{
m_row = matrix.GetLength();
m_col = matrix.GetLength();
m_data = matrix;
}
public Matrix(int ro, int co)
{
if (ro < || co < ) throw new Exception("");
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("");
Matrix re = new Matrix(left.Row, right.Column);
for (int i = ; i < left.Row; i++)
{
for (int j = ; j < right.Column; j++)
{
for (int k = ; k < left.Column; 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("");
Matrix re = new Matrix(left.Row, left.Column);
for (int i = ; i < left.Row; i++)
{
for (int j = ; j < left.Column; 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("");
Matrix re = new Matrix(left.Row, left.Column);
for (int i = ; i < left.Row; i++)
{
for (int j = ; j < left.Column; 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 = ; i < right.Row; i++)
{
for (int j = ; j < right.Column; j++)
{
re[i, j] = right[i, j] * factor;
}
}
return re;
}
public static Matrix operator *(Matrix left, double factor)
{
return factor * left;
}
/// <summary>转置
/// </summary>
/// <returns></returns>
public Matrix Matrixtran()
{
Matrix re = new Matrix(this.m_col, this.m_row);
for (int i = ; i < this.m_row; i++)
{
for (int j = ; j < this.m_col; j++)
{
re[j, i] = this[i, j];
}
}
return re;
}
/// <summary>行列式 //加边法
/// </summary>
/// <param name="Matrix"></param>
/// <returns></returns>
public double Matrixvalue()
{
if (this.m_row != this.m_col)
{ throw new Exception(""); }
int n = this.m_row;
if (n == ) return this[, ] * this[, ] - this[, ] * this[, ];
double dsum = , dSign = ;
for (int i = ; i < n; i++)
{
Matrix tempa = new Matrix(n - , n - );
for (int j = ; j < n - ; j++)
{
for (int k = ; k < n - ; k++)
{
tempa[j, k] = this[j + , k >= i ? k + : k];
}
}
dsum += this[, i] * dSign * tempa.Matrixvalue();
dSign = dSign * -;
}
return dsum;
}
/// <summary>求逆
/// </summary>
/// <param name="Matrix"></param>
/// <returns></returns>
public Matrix InverseMatrix()
{
int row = this.m_row; int col = this.m_col;
if (row != col) throw new Exception("");
Matrix re = new Matrix(row, col);
double val = this.Matrixvalue();
if (Math.Abs(val) <= 1E-) { throw new Exception(""); }
re = this.AdjointMatrix();
for (int i = ; i < row; i++)
{
for (int j = ; j < row; j++)
{
re[i, j] = re[i, j] / val;
}
}
return re; }
/// <summary>求伴随矩阵
/// </summary>
/// <param name="Matrix"></param>
/// <returns></returns>
public Matrix AdjointMatrix()
{
int row = this.m_row;
Matrix re = new Matrix(row, row);
for (int i = ; i < row; i++)
{
for (int j = ; j < row; j++)
{
Matrix temp = new Matrix(row - , row - );
for (int x = ; x < row - ; x++)
{
for (int y = ; y < row - ; y++)
{
temp[x, y] = this[x < i ? x : x + , y < j ? y : y + ];
}
}
re[j, i] = ((i + j) % == ? : -) * temp.Matrixvalue();
}
}
return re;
}
}

一些基本的几何运算

 public class CalcCls
{ /// <summary>
/// 根据两点计算距离两点连线为R的两点,默认垂足为A
/// </summary>
/// <param name="pointa">A 已知点</param>
/// <param name="pointb">B 已知点</param>
/// <param name="R">距离</param>
/// <param name="pointc">C 待求点</param>
/// <param name="pointd">D 待求点</param>
/// <returns>AB两点重合返回false 正常为true</returns>
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;
}
}
/// <summary> 判断pt在pa到pb的左侧</summary>
/// <returns></returns>
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 < )
{
return false;
}
else
{
return true;
}
} /// <summary> 计算P1P2和P3P4两条线段所在直线的交点
/// 如果两条线段在同一直线,返回较短的线段的端点,p2或P3</summary>
/// <param name="pt">输出交点</param>
/// <returns>有交点返回true 否则返回false</returns>
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 == )//平行或共线
{
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;
}
}
/// <summary>判断P1P2和P3P4线段是否相交</summary>
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) >= &&
multiply(pt1, pt4, pt3) * multiply(pt4, pt2, pt3) >= )
{
return true;
} }
return false;
}
/******************************************************************************
r=multiply(sp,ep,op),得到(sp-op)*(ep-op)的叉积
r>0:ep在矢量opsp的逆时针方向;
r=0:opspep三点共线;
r<0:ep在矢量opsp的顺时针方向
*******************************************************************************/
/// <summary> 计算p1p0和p2p0叉积 </summary>
/// <returns></returns>
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; }
/// <summary>按照距离将交点排序 </summary>
/// <param name="temline"></param>
/// <param name="ps">起点</param>
/// <returns></returns>
protected PointXY[] sortPoint(PointXY[] temline, PointXY ps)
{
List<PointXY> lp = new List<PointXY>();
List<PointXY> sortlp = new List<PointXY>();
lp.AddRange(temline);
if (temline.Length < ) return sortlp.ToArray();
for (; lp.Count > ; )
{
PointXY pd = lp[];
for (int i = ; i < lp.Count - ; i++)
{
if (Distance(ps, pd) > Distance(ps, lp[i + ]))
{
pd = lp[i + ];
}
}
lp.Remove(pd);
sortlp.Add(pd);
}
sortlp.Add(lp[]);
return sortlp.ToArray();
} /// <summary>
/// 根据两点计算两点连线上距离A点L的点 输出C点为距离B近的点上的点 D为距离B远的点
/// </summary>
/// <param name="pointa">A点 默认为计算距离A点L的点</param>
/// <param name="pointb">B点</param>
/// <param name="L">距离</param>
/// <param name="pointc">返回点C</param>
/// <param name="pointd">返回点D 有时候没用</param>
/// <returns></returns>
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;
}
} /// <summary> 返回两点的距离 </summary>
/// <param name="pa"></param>
/// <param name="pb"></param>
/// <returns></returns>
public double Distance(double xa, double ya, double xb, double yb)
{
double L;
L = Math.Sqrt(Math.Pow(xa - xb, ) + Math.Pow(ya - yb, ));
return L;
}
public double Distance(PointXY pa, PointXY pb)
{
return Distance(pa.X, pa.Y, pb.X, pb.Y);
} /// <summary> 用VS自带算法判断点是否在区域内 </summary>
/// <param name="pt"></param>
/// <param name="pointsArray"></param>
/// <returns></returns>
public bool PtInPolygon(PointXY pd, PointXY[] pdsArray)
{
PointF pt = new PointF();
pt.X = (float)pd.X;
pt.Y = (float)pd.Y;
List<Point> pl = new List<Point>();
for (int i = ; i < pdsArray.Length; i++)
{
Point p = new Point();
p.X = (int)pdsArray[i].X;
p.Y = (int)pdsArray[i].Y;
pl.Add(p);
}
if (pl.Count < ) return false;
using (System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath())
{
gp.AddPolygon(pl.ToArray());
return gp.IsVisible(pt);
}
} /// <summary>
/// 求线段的方位角0-360
/// </summary>
/// <param name="pa">线段起点</param>
/// <param name="pb">线段终点</param>
/// <returns>从0度顺时针偏转到该线段所划过的角度</returns>
protected double Angle(PointXY pa, PointXY pb)
{
double Ang = ;
double a;
try
{
a = Math.Acos((pb.X - pa.X) / Distance(pa, pb)); if (pb.Y - pa.Y < )
{
a = * Math.PI - a;
}
Ang = a * 180d / Math.PI;
return Ang;
}
catch
{
Ang = ;
return Ang;
}
} /// <summary>角度到弧度</summary>
/// <param name="value"></param>
/// <returns></returns>
private double AngleToRadian(double value)
{
return value * Math.PI / 180d;
} /// <summary> 弧度到角度</summary>
/// <param name="value"></param>
/// <returns></returns>
private double RadianToAngle(double value)
{
return value * 180d / Math.PI;
} } public struct PointXY
{
public double Y;
public double X; }

C# 矩阵运算和一些基本的几何运算的更多相关文章

  1. 基于js的地理数据的几何运算turfjs

    Doc: http://turfjs.org/static/docs/global.html Openlayers3 Sample: http://jsfiddle.net/d6o81vc7/

  2. C++矩阵运算库推荐

    最近在几个地方都看到有人问C++下用什么矩阵运算库比较好,顺便做了个调查,做一些相关的推荐吧.主要针对稠密矩阵,有时间会再写一个稀疏矩阵的推荐. Armadillo:C++下的Matlab替代品 地址 ...

  3. NOIP2002矩形覆盖[几何DFS]

    题目描述 在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示.例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4(0,7),见图一. 这 ...

  4. Python之Numpy:线性代数/矩阵运算

    当你知道工具的用处,理论与工具如何结合的时候,通常会加速咱们对两者的学习效率. 零 numpy 那么,Numpy是什么? NumPy(Numerical Python) 是 Python 语言的一个扩 ...

  5. Python 图像处理 OpenCV (9):图像处理形态学开运算、闭运算以及梯度运算

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  6. OpenCV计算机视觉学习(5)——形态学处理(腐蚀膨胀,开闭运算,礼帽黑帽,边缘检测)

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 形态 ...

  7. TF(2): 核心概念

    TF的核心是围绕Graph展开的,简而言之,就是Tensor沿着Graph传递闭包完成Flow的过程.所以在介绍Graph之前需要讲述一下符号编程.计算流图.梯度计算.控制流的概念. 张量(Tenso ...

  8. [TF] Architecture - Computational Graphs

    阅读笔记: 仅希望对底层有一定必要的感性认识,包括一些基本核心概念. Here只关注Graph相关,因为对编程有益. TF – Kernels模块部分参见:https://mp.weixin.qq.c ...

  9. [图解tensorflow源码] 入门准备工作附常用的矩阵计算工具[转]

    [图解tensorflow源码] 入门准备工作 附常用的矩阵计算工具[转] Link: https://www.cnblogs.com/yao62995/p/5773142.html  tensorf ...

随机推荐

  1. 搭建git服务器(临时服务器,命令行形式,针对2到5人左右,轻量)

    服务端配置 ############################################################################################## ...

  2. jeesite 的提示消息图标

    jeesite  的提示消息图标 jeesite 框架的提示信息 保存数据时 总是显示一个叉子图标 不符合要求 原因: 不加成功两字:如下 后来大神说 保存数据提示语句必须加“”“成功” 才会出现正确 ...

  3. 【算法笔记】B1018 锤子剪刀布

    1018 锤子剪刀布 (20 分) 大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示: 现给出两人的交锋记录,请统计双方的胜.平.负次数,并且给出双方分别出什么手势的胜算最大. ...

  4. 精神AC合集 2018.4.3

    UESTC炸了,先把看似十分OK(只是过了样例)的代码贴上,修复好后再交上去 594 #include<iostream> #include<algorithm> #inclu ...

  5. Codeforces - 240F 是男人就上26棵线段树

    #include<bits/stdc++.h> using namespace std; const int maxn = 1e5+11; typedef long long ll; ch ...

  6. MBR为什么不支持3T硬盘

    MBR,全称为Master Boot Record,即硬盘的主引导记录.(是管理硬盘分区的一种模式.升级版是GPT) MBR保存在硬盘的第1个扇区(即硬盘的0柱面.0磁头.1扇区).它由三个部分组成, ...

  7. jstl 遍历数据

    1   导入 jstl  的  jar 包 2. 页面中添加 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/ ...

  8. wamp下localhost目录Your Projects下项目无法打开解决方案

    最近在学PHP,然后可能遇到各种小白问题,记录下来当做自己成长的见证吧: wamp下localhost目录Your Projects下项目无法打开,但是在url中输入项目可以访问到. 解决方案: 注意 ...

  9. iptables 深入分析

    四表五链四表:filter , nat, manager, raw五链: 五个HOOK点的链接,pre_rout, foward, post_rout, in ,out 问题:内核如何匹配,内核使能 ...

  10. 分享一个js方法

    这是一个关于参数合并的方法,这个场景也经常遇到,比如我们现在要对微信小程序的wx.request进行再一次封装,会涉及到一些默认的参数和每次使用自己传递的参数合并问题,分享代码. var extend ...