123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768 |
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Linq;
- namespace SmartCoalApplication.Base.CommTool
- {
- /// <summary>
- /// 基础计算帮助类
- /// </summary>
- public class BasicCalculationHelper
- {
- /// <summary>
- /// 计算两点之间的距离
- /// </summary>
- /// <param name="startPoint">起点</param>
- /// <param name="endPoint">终点</param>
- /// <returns></returns>
- public static double GetDistance(Point startPoint, Point endPoint, int digit)
- {
- try
- {
- long x = System.Math.Abs(endPoint.X - startPoint.X);
- long y = System.Math.Abs(endPoint.Y - startPoint.Y);
- return Math.Round(Math.Sqrt(x * x + y * y), digit);
- }
- catch (Exception)
- {
- }
- return 0.0;
- }
- /// <summary>
- /// 计算两点之间的距离
- /// </summary>
- /// <param name="startPoint">起点</param>
- /// <param name="endPoint">终点</param>
- /// <returns></returns>
- public static double GetDistance(PointF startPoint, PointF endPoint)
- {
- try
- {
- float x = System.Math.Abs(endPoint.X - startPoint.X);
- float y = System.Math.Abs(endPoint.Y - startPoint.Y);
- return Math.Sqrt(x * x + y * y);
- }
- catch (Exception)
- {
- }
- return 0.0;
- }
- public static double GetDistance(PointF startPoint, PointF endPoint, int digit)
- {
- try
- {
- long x = System.Math.Abs((int)(endPoint.X - startPoint.X));
- long y = System.Math.Abs((int)(endPoint.Y - startPoint.Y));
- return Math.Round(Math.Sqrt(x * x + y * y), digit);
- }
- catch (Exception)
- {
- }
- return 0.0;
- }
- /// <summary>
- /// opencv的仿射变换
- /// </summary>
- /// <param name="src"></param>
- /// <param name="center"></param>
- /// <param name="angle"></param>
- /// <returns></returns>
- public static OpenCvSharp.Point GetPointAffinedPos(OpenCvSharp.Point src, OpenCvSharp.Point center, double angle)
- {
- OpenCvSharp.Point dst;
- int x = src.X - center.X;
- int y = src.Y - center.Y;
- dst.X = (int)Math.Round(x * Math.Cos(angle) + y * Math.Sin(angle) + center.X);
- dst.Y = (int)Math.Round(-x * Math.Sin(angle) + y * Math.Cos(angle) + center.Y);
- return dst;
- }
- /// <summary>
- /// 计算轮廓内最左和最右点的距离
- /// </summary>
- /// <returns></returns>
- public static int GetLeftAndRightDistance(OpenCvSharp.Point[] points)
- {
- OpenCvSharp.Point left = points[0];
- OpenCvSharp.Point right = points[0];
- foreach (OpenCvSharp.Point p in points)
- {
- if (left.X > p.X)
- {
- left = p;
- }
- if (right.X < p.X)
- {
- right = p;
- }
- }
- return right.X - left.X;
- }
- public static List<int> GetCaliperDiameter(OpenCvSharp.Point[] contours, OpenCvSharp.HierarchyIndex hierarchyIndex)
- {
- //计算结果
- List<int> vs = new List<int>();
- //每次旋转的角度
- double angle = 360 / 64;
- //计算中心点
- OpenCvSharp.Moments m = OpenCvSharp.Cv2.Moments(contours);
- double cx = m.M10 / m.M00;
- double cy = m.M01 / m.M00;
- for (int i = 0; i < 64; i++)
- {
- if (i == 0)
- {
- vs.Add(GetLeftAndRightDistance(contours));
- }
- else
- {
- if (contours.Length >= 5 && hierarchyIndex.Parent == -1 && !Double.IsNaN(cx))
- {
- try
- {
- OpenCvSharp.Point[] temps = new OpenCvSharp.Point[contours.Count()];
- for (int j = 0; j < contours.Count(); j++)
- {
- temps[j] = BasicCalculationHelper.GetPointAffinedPos(contours[j], new OpenCvSharp.Point(cx, cy), angle * i);
- }
- vs.Add(GetLeftAndRightDistance(temps));
- }
- catch (Exception)
- {
- }
- }
- /*else
- {
- vs.Add(0);
- }*/
- }
- }
- return vs;
- }
- /// <summary>
- /// 求第三个点到直线上的垂足的点
- /// </summary>
- /// <param name="start">构成直线的点1</param>
- /// <param name="end">构成直线的点2</param>
- /// <param name="three">线外的一点</param>
- /// <returns></returns>
- public static PointF GetDropFeet(PointF start, PointF end, PointF three)
- {
- PointF footPoint = new PointF();
- // 求直线斜率
- double k = (double)(end.Y - start.Y) / (end.X - start.X);
- //pointArray[0].X == pointArray[1].X || pointArray[0].Y == pointArray[1].Y
- if (double.IsInfinity(k) || Math.Abs(k) < 0.001) //垂线斜率不存在或斜率为0
- {
- if (k > 0)
- {
- footPoint.X = start.X;
- footPoint.Y = three.Y;
- }
- else if (k < 0)
- {
- footPoint.X = start.X;
- footPoint.Y = three.Y;
- }
- else
- {
- footPoint.Y = start.Y;
- footPoint.X = three.X;
- }
- }
- else
- {
- footPoint.X = (float)((k * start.X + three.X / k + three.Y - start.Y) / (1 / k + k));
- footPoint.Y = (float)(-1 / k * (footPoint.X - three.X) + three.Y);
- }
- return footPoint;
- }
- /// <summary>
- /// 已知直线上一点、斜率、线外一点,求垂足
- /// </summary>
- /// <param name="start">线上一点</param>
- /// <param name="k">斜率</param>
- /// <param name="three">线外一点</param>
- /// <returns></returns>
- public static PointF GetDropFeet(PointF start, double k, PointF three)
- {
- PointF footPoint = new PointF();
- if (double.IsInfinity(k) || Math.Abs(k) < 0.001) //垂线斜率不存在或斜率为0
- {
- if (k > 0)
- {
- footPoint.X = start.X;
- footPoint.Y = three.Y;
- }
- else if (k < 0)
- {
- footPoint.X = start.X;
- footPoint.Y = three.Y;
- }
- else
- {
- footPoint.Y = start.Y;
- footPoint.X = three.X;
- }
- }
- else
- {
- footPoint.X = (float)((k * start.X + three.X / k + three.Y - start.Y) / (1 / k + k));
- footPoint.Y = (float)(-1 / k * (footPoint.X - three.X) + three.Y);
- }
- return footPoint;
- }
- /// <summary>
- /// 三点计算角度,可能不对
- /// </summary>
- /// <param name="cen"></param>
- /// <param name="first"></param>
- /// <param name="second"></param>
- /// <returns></returns>
- public static double Angle(Point cen, Point first, Point second)
- {
- //判断象限
- int x = first.X - cen.X;
- int y = first.Y - cen.Y;
- int i = 0;
- if (x > 0 && y > 0) //第4象限
- {
- i = 4;
- }
- else if (x > 0 && y < 0) //第1象限
- {
- i = 1;
- }
- else if (x < 0 && y < 0) //第2象限
- {
- i = 2;
- }
- else if (x < 0 && y > 0) //第3象限
- {
- i = 3;
- }
- double ma_x = first.X - cen.X;
- double ma_y = first.Y - cen.Y;
- double mb_x = second.X - cen.X;
- double mb_y = second.Y - cen.Y;
- double v1 = (ma_x * mb_x) + (ma_y * mb_y);
- double ma_val = Math.Sqrt(ma_x * ma_x + ma_y * ma_y);
- double mb_val = Math.Sqrt(mb_x * mb_x + mb_y * mb_y);
- double cosM = v1 / (ma_val * mb_val);
- double angleAMB = Math.Acos(cosM) * 180 / Math.PI;
- if (i == 1) angleAMB = angleAMB - 90;
- if (i == 4) angleAMB = 90 - angleAMB;
- if (i == 3) angleAMB = angleAMB + 90;
- if (i == 2) angleAMB = 270 - angleAMB;
- return double.IsNaN(angleAMB) ? 0 : angleAMB;
- }
- public static double Angle(PointF cen, PointF first, PointF second)
- {
- //判断象限
- int x = (int)(first.X - cen.X);
- int y = (int)(first.Y - cen.Y);
- int i = 0;
- if (x > 0 && y > 0) //第4象限
- {
- i = 4;
- }
- else if (x > 0 && y < 0) //第1象限
- {
- i = 1;
- }
- else if (x < 0 && y < 0) //第2象限
- {
- i = 2;
- }
- else if (x < 0 && y > 0) //第3象限
- {
- i = 3;
- }
- double ma_x = first.X - cen.X;
- double ma_y = first.Y - cen.Y;
- double mb_x = second.X - cen.X;
- double mb_y = second.Y - cen.Y;
- double v1 = (ma_x * mb_x) + (ma_y * mb_y);
- double ma_val = Math.Sqrt(ma_x * ma_x + ma_y * ma_y);
- double mb_val = Math.Sqrt(mb_x * mb_x + mb_y * mb_y);
- double cosM = v1 / (ma_val * mb_val);
- double angleAMB = Math.Acos(cosM) * 180 / Math.PI;
- if (i == 1) angleAMB = angleAMB - 90;
- if (i == 4) angleAMB = 90 - angleAMB;
- if (i == 3) angleAMB = angleAMB + 90;
- if (i == 2) angleAMB = 270 - angleAMB;
- return double.IsNaN(angleAMB) ? 0 : angleAMB;
- }
- /// <summary>
- /// 三点计算角度,第二个写法
- /// </summary>
- /// <param name="P1X"></param>
- /// <param name="P1Y"></param>
- /// <param name="P2X"></param>
- /// <param name="P2Y"></param>
- /// <param name="P3X"></param>
- /// <param name="P3Y"></param>
- /// <returns></returns>
- public static double CalculateAngle(double P1X, double P1Y, double P2X, double P2Y,
- double P3X, double P3Y)
- {
- double numerator = P2Y * (P1X - P3X) + P1Y * (P3X - P2X) + P3Y * (P2X - P1X);
- double denominator = (P2X - P1X) * (P1X - P3X) + (P2Y - P1Y) * (P1Y - P3Y);
- double ratio = numerator / denominator;
- double angleRad = Math.Atan(ratio);
- double angleDeg = (angleRad * 180) / Math.PI;
- /*if (angleDeg < 0)
- {
- angleDeg = 180 + angleDeg;
- }*/
- /*if(angleDeg>360)
- {
- angleDeg = angleDeg - 360 * (angleDeg / 360);
- }*/
- //angleDeg = 180 - angleDeg;
- return -angleDeg;
- }
- /// <summary>
- /// 根据圆心点旋转另一个点
- /// </summary>
- /// <param name="point">圆上的点</param>
- /// <param name="center">圆心点</param>
- /// <param name="angle">旋转角度</param>
- /// <returns>返回旋转后的点的坐标</returns>
- public static Point GetAnglePoint(Point point, Point center, double angle)
- {
- Point p = new Point();
- angle = angle * Math.PI / 180;
- p.X = Convert.ToInt32((point.X - center.X) * Math.Cos(angle) - (point.Y - center.Y) * Math.Sin(angle) + center.X);
- p.Y = Convert.ToInt32((point.X - center.X) * Math.Sin(angle) + (point.Y - center.Y) * Math.Cos(angle) + center.Y);
- return p;
- }
- /// <summary>
- /// 计算夹角
- /// </summary>
- /// <param name="first">固定点</param>
- /// <param name="cen">圆心点</param>
- /// <param name="second">浮点</param>
- /// <returns>返回旋转后的点的坐标</returns>
- public static double CalculateAngle(PointF cen, PointF first, PointF second)
- {
- double ma_x = first.X - cen.X;
- double ma_y = first.Y - cen.Y;
- double mb_x = second.X - cen.X;
- double mb_y = second.Y - cen.Y;
- double v1 = (ma_x * mb_x) + (ma_y * mb_y);
- double ma_val = Math.Sqrt(ma_x * ma_x + ma_y * ma_y);
- double mb_val = Math.Sqrt(mb_x * mb_x + mb_y * mb_y);
- double cosM = v1 / (ma_val * mb_val);
- double angleAMB = Math.Acos(cosM) * 180 / Math.PI;
- if (second.Y < first.Y) angleAMB = -angleAMB;
- return angleAMB;
- }
- public static PointF GetAnglePoint(PointF point, PointF center, double angle)
- {
- PointF p = new PointF();
- angle = angle * Math.PI / 180;
- p.X = (float)((point.X - center.X) * Math.Cos(angle) - (point.Y - center.Y) * Math.Sin(angle) + center.X);
- p.Y = (float)((point.X - center.X) * Math.Sin(angle) + (point.Y - center.Y) * Math.Cos(angle) + center.Y);
- return p;
- }
- /// <summary>
- /// 计算宽高比
- /// </summary>
- /// <param name="points"></param>
- /// <returns></returns>
- public static double CalcAspectRatio(OpenCvSharp.Point[] points)
- {
- List<OpenCvSharp.Point> ps = points.ToList<OpenCvSharp.Point>();
- //最左侧的点
- int left = ps.Min<OpenCvSharp.Point>(a => a.X);
- //最右侧的点
- int right = ps.Max<OpenCvSharp.Point>(a => a.X);
- //最顶部的点
- int top = ps.Min<OpenCvSharp.Point>(a => a.Y);
- //最底部的点
- int bottom = ps.Max<OpenCvSharp.Point>(a => a.Y);
- int width = right - left;
- int height = bottom - top;
- if (width == 0 || height == 0)
- return 0;
- else
- return width * 1d / height;
- }
- /// <summary>
- /// 计算长径,找轮廓的最小外接圆
- /// </summary>
- /// <param name="points"></param>
- /// <returns></returns>
- public static double CalcLongTrail(OpenCvSharp.Point[] points)
- {
- if (points.Length < 5)
- return 0;
- OpenCvSharp.Point2f center;
- float radius = 0f;
- OpenCvSharp.Cv2.MinEnclosingCircle(points, out center, out radius);
- return radius;
- //OpenCvSharp.RotatedRect rect = OpenCvSharp.Cv2.FitEllipse(points);
- //return rect.Size.Height > rect.Size.Width ? rect.Size.Height : rect.Size.Width;
- }
- /// <summary>
- /// 保留两位小数进位
- /// </summary>
- /// <param name="value">double类型的值</param>
- /// <returns></returns>
- public static double DecimalCeiling(double value)
- {
- double values = Math.Round(value, 2);
- if (values < value)
- {
- values += Math.Pow(0.1, 2);
- }
- return values;
- }
- /// <summary>
- /// 保留两位小数不进位
- /// </summary>
- /// <param name="value">double类型的值</param>
- /// <returns></returns>
- public static double DecimalFloor(double value)
- {
- return double.Parse(value.ToString("F2"));
- }
- /// <summary>
- /// 计算长径,找轮廓的外接椭圆,计算椭圆的长径
- /// </summary>
- /// <param name="points"></param>
- /// <returns></returns>
- public static double CalcLongTrailEllipse(OpenCvSharp.Point[] points)
- {
- if (points.Length < 5)
- return 0;
- OpenCvSharp.RotatedRect rect = OpenCvSharp.Cv2.FitEllipse(points);
- return rect.Size.Height > rect.Size.Width ? rect.Size.Height : rect.Size.Width;
- }
- /// <summary>
- /// 计算曲线长度
- /// </summary>
- /// <param name="cen"></param>
- /// <param name="first"></param>
- /// <param name="second"></param>
- /// <returns></returns>
- private static double A = 4f / 14175f;
- private static int[] B = { 989, 5888, -928, 10496, -4540, 10496, -928, 5888, 989 };
- public static double curveLength(PointF[] mLeafPt)
- {
- if (mLeafPt == null || mLeafPt.Length == 1)
- {
- return 0f;
- }
- int n = mLeafPt.Length;
- PointF p0 = mLeafPt[0];
- PointF Pn = mLeafPt[n - 1];
- PointF[] tempArray = new PointF[n + 2];
- tempArray[0] = p0;
- tempArray[tempArray.Length - 1] = Pn;
- for (int i = 1; i < tempArray.Length - 1; i++)
- {
- tempArray[i] = mLeafPt[i - 1];
- }
- double a = 0f, b = 0.5f;
- double h = (b - a) / 8f;
- double length = 0f;
- for (int i = 0; i < n - 1; i++)
- {
- double integral = 0f;
- for (int j = 0; j <= 8; j++)
- {
- double t = a + j * h;
- double px = Px(tempArray[i].X, tempArray[i + 1].X, tempArray[i + 2].X, tempArray[i + 1].X, t);
- double py = Px(tempArray[i].Y, tempArray[i + 1].Y, tempArray[i + 2].Y, tempArray[i + 1].Y, t);
- double f = (double)Math.Sqrt(px * px + py * py);
- integral += B[j] * f;
- }
- integral *= h * A;
- length += integral;
- }
- return length;
- }
- private static double Px(float p1, float p2, float p3, float p4, double t)
- {
- return (-12f * t * t + 8 * t - 1) * p1 + (36 * t * t - 20 * t) * p2 + (-36 * t * t + 16 * t + 1) * p3 + (12 * t * t - 4 * t) * p4;
- }
- /// <summary>
- /// 三点角计算
- /// </summary>
- /// <param name="cen"></param>
- /// <param name="first"></param>
- /// <param name="second"></param>
- /// <returns></returns>
- public static double AngleText(PointF cen, PointF first, PointF second)
- {
- const double M_PI = 3.1415926535897;
- double ma_x = first.X - cen.X;
- double ma_y = first.Y - cen.Y;
- double mb_x = second.X - cen.X;
- double mb_y = second.Y - cen.Y;
- double v1 = (ma_x * mb_x) + (ma_y * mb_y);
- double ma_val = Math.Sqrt(ma_x * ma_x + ma_y * ma_y);
- double mb_val = Math.Sqrt(mb_x * mb_x + mb_y * mb_y);
- double cosM = v1 / (ma_val * mb_val);
- double angleAMB = Math.Acos(cosM) * 180 / M_PI;
- return angleAMB;
- }
- ///<summary>
- ///点到直线距离
- /// </summary>
- /// <param name="point1">线上的1点</param>
- /// <param name="point2">线上的2点</param>
- /// <param name="point3">线外的点</param>
- public static double pointToLine(Point point1, Point point2, Point point3)
- {
- double space = 0;
- double a, b, c;
- a = GetDistance(point1, point2, 7);// 线段的长度
- b = GetDistance(point1, point3, 7);// (x1,y1)到点的距离
- c = GetDistance(point2, point3, 7);// (x2,y2)到点的距离
- if (c <= 0.000001 || b <= 0.000001)
- {
- space = 0;
- return space;
- }
- if (a <= 0.000001)
- {
- space = b;
- return space;
- }
- if (c * c >= a * a + b * b)
- {
- space = b;
- return space;
- }
- if (b * b >= a * a + c * c)
- {
- space = c;
- return space;
- }
- double p = (a + b + c) / 2;// 半周长
- double s = Math.Sqrt(p * (p - a) * (p - b) * (p - c));// 海伦公式求面积
- space = 2 * s / a;// 返回点到线的距离(利用三角形面积公式求高)
- return space;
- }
- /// <summary>
- /// 计算多边形周长
- /// </summary>
- /// <param name="Points">多边形顶点</param>
- /// <param name="digit">小数位数</param>
- /// <returns></returns>
- public static double GetPolygonPerimeter(PointF[] Points, int digit)
- {
- float x;
- float y;
- int j = 0;
- double length = 0.0;
- for (int i = 0; i < Points.Length; i++)
- {
- if (i == Points.Length - 1)
- j = -1;
- else
- j = i;
- x = System.Math.Abs(Points[j + 1].X - Points[i].X);
- y = System.Math.Abs(Points[j + 1].Y - Points[i].Y);
- length = length + Math.Round(Math.Sqrt(x * x + y * y), digit);
- }
- return length;
- }
- /// <summary>
- /// 计算多边形面积
- /// </summary>
- /// <param name="Points"></param>
- /// <param name="digit"></param>
- /// <returns></returns>
- public static double GetPolygonArea(List<PointF> points)
- {
- var count = points.Count;
- double area0 = 0;
- double area1 = 0;
- for (int i = 0; i < count; i++)
- {
- double x = points[i].X;
- double y = i + 1 < count ? points[i + 1].Y : points[0].Y;
- area0 += x * y;
- double lat = points[i].Y;
- double lon = i + 1 < count ? points[i + 1].X : points[0].X;
- area1 += lat * lon;
- }
- return Math.Round(Math.Abs(0.5 * (area0 - area1)), 10);
- }
- /// <summary>
- /// 计算两条直线的交点
- /// </summary>
- /// <param name="lineFirstStar">L1的点1坐标</param>
- /// <param name="lineFirstEnd">L1的点2坐标</param>
- /// <param name="lineSecondStar">L2的点1坐标</param>
- /// <param name="lineSecondEnd">L2的点2坐标</param>
- /// <returns></returns>
- public static PointF GetIntersection(PointF lineFirstStar, PointF lineFirstEnd, PointF lineSecondStar, PointF lineSecondEnd)
- {
- /*
- * L1,L2都存在斜率的情况:
- * 直线方程L1: ( y - y1 ) / ( y2 - y1 ) = ( x - x1 ) / ( x2 - x1 )
- * => y = [ ( y2 - y1 ) / ( x2 - x1 ) ]( x - x1 ) + y1
- * 令 a = ( y2 - y1 ) / ( x2 - x1 )
- * 有 y = a * x - a * x1 + y1 .........1
- * 直线方程L2: ( y - y3 ) / ( y4 - y3 ) = ( x - x3 ) / ( x4 - x3 )
- * 令 b = ( y4 - y3 ) / ( x4 - x3 )
- * 有 y = b * x - b * x3 + y3 ..........2
- *
- * 如果 a = b,则两直线平等,否则, 联解方程 1,2,得:
- * x = ( a * x1 - b * x3 - y1 + y3 ) / ( a - b )
- * y = a * x - a * x1 + y1
- *
- * L1存在斜率, L2平行Y轴的情况:
- * x = x3
- * y = a * x3 - a * x1 + y1
- *
- * L1 平行Y轴,L2存在斜率的情况:
- * x = x1
- * y = b * x - b * x3 + y3
- *
- * L1与L2都平行Y轴的情况:
- * 如果 x1 = x3,那么L1与L2重合,否则平等
- *
- */
- float a = 0, b = 0;
- int state = 0;
- if (lineFirstStar.X != lineFirstEnd.X)
- {
- a = (lineFirstEnd.Y - lineFirstStar.Y) / (lineFirstEnd.X - lineFirstStar.X);
- state |= 1;
- }
- if (lineSecondStar.X != lineSecondEnd.X)
- {
- b = (lineSecondEnd.Y - lineSecondStar.Y) / (lineSecondEnd.X - lineSecondStar.X);
- state |= 2;
- }
- switch (state)
- {
- case 0: //L1与L2都平行Y轴
- {
- if (lineFirstStar.X == lineSecondStar.X)
- {
- //throw new Exception("两条直线互相重合,且平行于Y轴,无法计算交点。");
- return new PointF(0, 0);
- }
- else
- {
- //throw new Exception("两条直线互相平行,且平行于Y轴,无法计算交点。");
- return new PointF(0, 0);
- }
- }
- case 1: //L1存在斜率, L2平行Y轴
- {
- float x = lineSecondStar.X;
- float y = (lineFirstStar.X - x) * (-a) + lineFirstStar.Y;
- return new PointF(x, y);
- }
- case 2: //L1 平行Y轴,L2存在斜率
- {
- float x = lineFirstStar.X;
- //网上有相似代码的,这一处是错误的。你可以对比case 1 的逻辑 进行分析
- //源code:lineSecondStar * x + lineSecondStar * lineSecondStar.X + p3.Y;
- float y = (lineSecondStar.X - x) * (-b) + lineSecondStar.Y;
- return new PointF(x, y);
- }
- case 3: //L1,L2都存在斜率
- {
- if (a == b)
- {
- // throw new Exception("两条直线平行或重合,无法计算交点。");
- return new PointF(0, 0);
- }
- float x = (a * lineFirstStar.X - b * lineSecondStar.X - lineFirstStar.Y + lineSecondStar.Y) / (a - b);
- float y = a * x - a * lineFirstStar.X + lineFirstStar.Y;
- return new PointF(x, y);
- }
- }
- // throw new Exception("不可能发生的情况");
- return new PointF(0, 0);
- }
- public static List<List<OpenCvSharp.Point>> GetWholeContoursTree(OpenCvSharp.Point[][] contours, OpenCvSharp.HierarchyIndex[] hierarchyIndex, int k)
- {
- List<List<OpenCvSharp.Point>> wholeContours = new List<List<OpenCvSharp.Point>>();
- wholeContours.Add(contours[k].ToList());
- if (hierarchyIndex[k].Child > 0)
- {
- RecursionGetWholeContoursTree(wholeContours, contours, hierarchyIndex, k);
- }
- return wholeContours;
- }
- public static void RecursionGetWholeContoursTree(List<List<OpenCvSharp.Point>> wholeContours, OpenCvSharp.Point[][] contours, OpenCvSharp.HierarchyIndex[] hierarchyIndex, int k)
- {
- if (hierarchyIndex[k].Child > 0)
- {
- for (int i = 0; i < hierarchyIndex.Length; i++)
- {
- if (hierarchyIndex[i].Parent == k)
- {
- wholeContours.Add(contours[i].ToList());
- if (hierarchyIndex[i].Child > 0)
- {
- RecursionGetWholeContoursTree(wholeContours, contours, hierarchyIndex, i);
- }
- }
- }
- }
- }
- }
- }
|