tangxu
2024-10-09 b1cee427f6383b243b8c0aa45aabce9f58075d8d
添加装置曲线辅助类
已修改2个文件
已添加4个文件
1285 ■■■■■ 文件已修改
WinFrmUI/HStation.WinFrmUI.Auth.Core/FakesAssemblies/Yw.Untity.Core.3.0.0.0.Fakes.dll 补丁 | 查看 | 原始文档 | blame | 历史
WinFrmUI/HStation.WinFrmUI.Auth.Core/FakesAssemblies/Yw.Untity.Core.3.0.0.0.Fakes.messages 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WinFrmUI/Yw.WinFrmUI.Phart.Core/抛物线/LineHelper.cs 463 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WinFrmUI/Yw.WinFrmUI.Phart.Core/抛物线/ParabolaCurveHelper.cs 524 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WinFrmUI/Yw.WinFrmUI.Phart.Core/装置曲线/EquipCurveHelper.cs 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WinFrmUI/Yw.WinFrmUI.Phart.Core/装置曲线/EquipCurveParas.cs 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WinFrmUI/HStation.WinFrmUI.Auth.Core/FakesAssemblies/Yw.Untity.Core.3.0.0.0.Fakes.dll
Binary files differ
WinFrmUI/HStation.WinFrmUI.Auth.Core/FakesAssemblies/Yw.Untity.Core.3.0.0.0.Fakes.messages
@@ -1,15 +1,15 @@
D:\WorkData\git\HStation\XHS\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.DataTableExtension ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\git\HStation\XHS\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.DateTimeExtension ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\git\HStation\XHS\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.EnumerableExtension ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\git\HStation\XHS\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.EnumExtension ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\git\HStation\XHS\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.ListExtension ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\git\HStation\XHS\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.PointExtension ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\git\HStation\XHS\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.PointFExtension ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\git\HStation\XHS\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.StringExtension ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\git\HStation\XHS\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.StringListExtension ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\git\HStation\XHS\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.EnumUtil ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\git\HStation\XHS\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.ReflectionUtil ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\git\HStation\XHS\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.DateTimeHelper ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\git\HStation\XHS\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.TransExp<TIn, TOut> ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\git\HStation\XHS\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.UserRegisterContext ç”Ÿæˆå­˜æ ¹: ç±»åž‹å¯¹ exported or assembly(Yw.Untity.Core.3.0.0.0.Fakes) ä¸å¯è§ã€‚
D:\WorkData\git\HStation\XHS\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.UserRegisterContext ç”Ÿæˆå¡«å……码: ç±»åž‹å¯¹ exported or assembly(Yw.Untity.Core.3.0.0.0.Fakes) ä¸å¯è§ã€‚
D:\WorkData\HStation\XHS\XHS.V1.0\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.DataTableExtension ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\HStation\XHS\XHS.V1.0\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.DateTimeExtension ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\HStation\XHS\XHS.V1.0\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.EnumerableExtension ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\HStation\XHS\XHS.V1.0\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.EnumExtension ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\HStation\XHS\XHS.V1.0\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.ListExtension ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\HStation\XHS\XHS.V1.0\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.PointExtension ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\HStation\XHS\XHS.V1.0\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.PointFExtension ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\HStation\XHS\XHS.V1.0\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.StringExtension ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\HStation\XHS\XHS.V1.0\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.StringListExtension ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\HStation\XHS\XHS.V1.0\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.EnumUtil ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\HStation\XHS\XHS.V1.0\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.ReflectionUtil ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\HStation\XHS\XHS.V1.0\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.DateTimeHelper ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\HStation\XHS\XHS.V1.0\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.TransExp<TIn, TOut> ç”Ÿæˆå­˜æ ¹: ç±»åž‹æ²¡æœ‰å¯¹ç¨‹åºé›†å¯è§çš„æž„造函数。构造函数本身或参数可能不可见。。
D:\WorkData\HStation\XHS\XHS.V1.0\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.UserRegisterContext ç”Ÿæˆå­˜æ ¹: ç±»åž‹å¯¹ exported or assembly(Yw.Untity.Core.3.0.0.0.Fakes) ä¸å¯è§ã€‚
D:\WorkData\HStation\XHS\XHS.V1.0\WinFrmUI\HStation.WinFrmUI.Auth.Core\Fakes\Yw.Untity.Core.fakes : warning : æ— æ³•为 Yw.Untity.UserRegisterContext ç”Ÿæˆå¡«å……码: ç±»åž‹å¯¹ exported or assembly(Yw.Untity.Core.3.0.0.0.Fakes) ä¸å¯è§ã€‚
WinFrmUI/Yw.WinFrmUI.Phart.Core/Å×ÎïÏß/LineHelper.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,463 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Yw.Geometry
{
    /// <summary>
    /// ç›´çº¿è¾…助类
    /// </summary>
    public static class Line2dHelper
    {
        /// <summary>
        /// æ˜¯å¦åž‚ç›´
        /// </summary>
        /// <param name="k"></param>
        /// <returns></returns>
        public static bool IsVerticalK(double k)
        {
            if (k >= 100000000 - 1)
                return true;
            else
                return false;
        }
        private const double vertical_k = 100000000;//垂直时K的值
        //直线插值
        public static double GetLineInsert(double X1, double X2, double Y1, double Y2, double X)
        {
            if (Math.Abs(X2 - X1) < 0.000001)
            {
                //MessageBox.Show("输入值X2与X1不能相同!", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return 0;
            }
            if (Math.Abs(Y2 - Y1) < 0.000001)
            {
                //MessageBox.Show("输入值Y2与Y1不能相同!", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return 0;
            }
            double Y = Y1 + (Y2 - Y1) / (X2 - X1) * (X - X1);
            return Y;
        }
        //是否一个点向x轴的射线穿透线段,有交点且在线的左边
        public static bool IsIntersectLeft(Yw.Geometry.Point2d basePoint, Yw.Geometry.Point2d pt1, Yw.Geometry.Point2d pt2)
        {
            return IsIntersectLeft(basePoint.X, basePoint.Y, pt1.X, pt1.Y, pt2.X, pt2.Y);
        }
        public static bool IsIntersectLeft(double x, double y, double x1, double y1, double x2, double y2)
        {
            double maxY = y1 > y2 ? y1 : y2;
            double minY = y1 > y2 ? y2 : y1;
            if (Math.Abs(y2 - y1) < 0.000001)
            {
                if (Math.Abs(y - y1) < 0.000001)
                    return true;
                else
                    return false;
            }
            bool IsInLine = false;
            if (y < maxY && y >= minY)
            {
                if (x <= (x1 + (x2 - x1) * (y - y1) / (y2 - y1)))
                {
                    IsInLine = true;
                }
            }
            return IsInLine;
        }
        //X1和X2之间连一条线, åœ¨æ¯”率ratio处点的坐标
        public static double GetRatioPoint(double X1, double X2, double ratio)
        {
            double X3 = 0.0;
            X3 = X1 + ratio * (X2 - X1);
            return X3;
        }
        //X1,Y1和X2 Y2之间连一条线,在X处点的Y坐标
        public static double GetYbyX(double X1, double Y1, double X2, double Y2, double X)
        {
            if (Math.Abs(X1 - X2) < 0.000001)
                return Y1;
            if (Math.Abs(Y1 - Y2) < 0.000001)
                return Y1;
            double k = 0, b = 0;
            if (!GetKandB(X1, Y1, X2, Y2, ref k, ref b))
                return Y1;
            double Y = 0;
            Y = k * X + b;
            return Y;
        }
        //X1,Y1和X2 Y2之间连一条线,在Y处点的X坐标
        public static double GetXbyY(double X1, double Y1, double X2, double Y2, double Y)
        {
            if (Math.Abs(X1 - X2) < 0.000001)
                return X1;
            if (Math.Abs(Y1 - Y2) < 0.000001)
                return X1;
            double k = 0, b = 0;
            if (!GetKandB(X1, Y1, X2, Y2, ref k, ref b))
                return X1;
            double X = (Y - b) / k;
            return X;
        }
        //输入(X1,Y1),(X1,Y1)生成直线,返回直线的k和b y=kx+b
        public static bool GetKandB(double X1, double Y1, double X2, double Y2, ref double k, ref double b)
        {
            if (Math.Abs(X1 - X2) < 0.000001)
            {
                k = vertical_k;
                b = Y2;
                return false;
            }
            else
            {
                k = (Y1 - Y2) / (X1 - X2);
                b = Y1 - (Y1 - Y2) * X1 / (X1 - X2);
                return true;
            }
        }
        //输入(X1,Y1),(X1,Y1)生成直线,返回直线的k和b y=kx+b
        public static bool GetKandB(Yw.Geometry.Point2d pt1, Yw.Geometry.Point2d pt2, ref double k, ref double b)
        {
            if (pt1 == null || pt2 == null)
                return false;
            double X1 = pt1.X;
            double Y1 = pt1.Y;
            double X2 = pt2.X;
            double Y2 = pt2.Y;
            if (Math.Abs(X1 - X2) < 0.000001)
            {
                k = vertical_k;
                b = Y2;
                return false;
            }
            else
            {
                k = (Y1 - Y2) / (X1 - X2);
                b = Y1 - (Y1 - Y2) * X1 / (X1 - X2);
                return true;
            }
        }
        //通过2点,得到通过这2点的直线的k,b  çº¿çš„形式是 y=k*x+b,竖直返回false
        public static bool GetKandB(Yw.Geometry.Point2d pt1, Yw.Geometry.Point2d pt2, out double k, out double b,double ingoreDis = 0.000001)
        {
            k = 0;
            b = 0;
            if (Math.Abs(pt1.X - pt2.X) < ingoreDis)
            {//竖直
                k = vertical_k;
                b = pt1.X;
                return false;
            }
            if (Math.Abs(pt1.Y - pt2.Y) < ingoreDis)
            {//平行
                k = 0;
                b = pt1.X;
                return true;
            }
            k = (pt1.Y - pt2.Y) / (pt1.X - pt2.X);// Math.Atan((pt1.Y - pt2.Y) / (pt1.X - pt2.X)) * 180 / Math.PI;
            b = pt1.Y - k * pt1.X;
            return true;
        }
        //取中间点
        public static Yw.Geometry.Point2d GetMiddlePoint(Yw.Geometry.Point2d pt1, Yw.Geometry.Point2d pt2)
        {
            return new Yw.Geometry.Point2d((pt1.X + pt2.X) * 0.5, (pt1.Y + pt2.Y) * 0.5);
        }
        //取内部点
        public static Yw.Geometry.Point2d GetInnerPoint(Yw.Geometry.Point2d startPt, Yw.Geometry.Point2d endPt, double ratio)
        {
            if (startPt == null || endPt == null)
                return null;
            return new Yw.Geometry.Point2d(startPt.X + (endPt.X - startPt.X) * ratio, startPt.Y + (endPt.Y - startPt.Y) * ratio);
        }
        //是否是内部点
        public static bool IsInnerPoint(Yw.Geometry.Point2d startPt, Yw.Geometry.Point2d endPt, Yw.Geometry.Point2d pt)
        {
            if (startPt == null || endPt == null)
                return false ;
            if (pt.X < startPt.X && pt.X > endPt.X)
                return true;
            if (pt.X > startPt.X && pt.X < endPt.X)
                return true;
            return false;
        }
        //是否是内部点
        public static bool IsInnerPointByX(Yw.Geometry.Point2d startPt, Yw.Geometry.Point2d endPt, Yw.Geometry.Point2d pt)
        {
            if (startPt == null || endPt == null)
                return false ;
            if (pt.X < startPt.X && pt.X > endPt.X)
                return true;
            if (pt.X > startPt.X && pt.X < endPt.X)
                return true;
            return false;
        }
        //
        public static bool IsInnerPointByY(Yw.Geometry.Point2d startPt, Yw.Geometry.Point2d endPt, Yw.Geometry.Point2d pt)
        {
            if (startPt == null || endPt == null)
                return false ;
            if (pt.Y < startPt.X && pt.Y > endPt.Y)
                return true;
            if (pt.Y > startPt.X && pt.Y < endPt.Y)
                return true;
            return false;
        }
        /// <summary>
        /// è®¡ç®—交点(没有 å°±è¿”回null)
        /// </summary>
        /// <param name="startPt"></param>
        /// <param name="endPt"></param>
        /// <returns></returns>
        public static Yw.Geometry.Point2d GetCrossPoint(Yw.Geometry.Point2d startPt1, Yw.Geometry.Point2d endPt1, Yw.Geometry.Point2d startPt2, Yw.Geometry.Point2d endPt2)
        {
            if (startPt1 == null || endPt1 == null)
                return null;
            if (startPt2 == null || endPt2 == null)
                return null;
            double k1, b1;
            GetKandB(startPt1, endPt1, out k1, out b1);
            double k2, b2;
            GetKandB(startPt2, endPt2, out k2, out b2);
            if (Math.Abs(k1 - k2) < 0.000001)
                return null;
            if (k1 == vertical_k)
            {//垂直
                return new Yw.Geometry.Point2d(startPt1.X, startPt1.X * k2 + b2);
            }
            if (k2 == vertical_k)
            {//垂直
                return new Yw.Geometry.Point2d(startPt2.X, startPt2.X * k1 + b1 );
            }
            double sect_x = (b2-b1)/(k1-k2);
            return new Yw.Geometry.Point2d(sect_x, sect_x * k1 + b1);
        }
        /// <summary>
        /// æ˜¯å¦å¹³è¡Œ
        /// </summary>
        /// <param name="startPt1"></param>
        /// <param name="endPt1"></param>
        /// <param name="startPt2"></param>
        /// <param name="endPt2"></param>
        /// <returns></returns>
        public static bool IsParallel(Yw.Geometry.Point2d startPt1, Yw.Geometry.Point2d endPt1, Yw.Geometry.Point2d startPt2, Yw.Geometry.Point2d endPt2)
        {
            if (startPt1 == null || endPt1 == null)
                return false;
            if (startPt2 == null || endPt2 == null)
                return false;
            double k1, b1;
            GetKandB(startPt1, endPt1, out k1, out b1);
            double k2, b2;
            GetKandB(startPt2, endPt2, out k2, out b2);
            if (Math.Abs(k1 - k2) < 0.000001)
                return true;
            else
                return false;
        }
        //三个点在同一条直线上,输入(X1,Y1),(X2,Y2)以及沿(X2,Y2)侧延长Length,得到的点(X3,Y3)
        public static Yw.Geometry.Point2d GetExtendPoint(Yw.Geometry.Point2d startPt, Yw.Geometry.Point2d endPt, double exLength)
        {
            return GetExtendPointByLength(startPt, endPt, exLength);
        }
        //三个点在同一条直线上,输入(X1,Y1),(X2,Y2)以及沿(X2,Y2)侧延长Length,得到的点(X3,Y3)
        public static Yw.Geometry.Point2d GetExtendPointByLength(Yw.Geometry.Point2d startPt, Yw.Geometry.Point2d endPt, double exLength)
        {
            if (startPt == null || endPt == null)
                return null;
            double betweenLength = GetPointDistance(startPt, endPt);
            if (betweenLength < 0.01)
                return startPt;
            double ex_ratio = (betweenLength + exLength) / betweenLength;
            Yw.Geometry.Point2d extPt = new Yw.Geometry.Point2d();
            extPt.X = (endPt.X - startPt.X) * ex_ratio + startPt.X;
            extPt.Y = (endPt.Y - startPt.Y) * ex_ratio + startPt.Y;
            return extPt;
        }
        public static double GetPointDistance(Yw.Geometry.Point2d pt1, Yw.Geometry.Point2d pt2)
        {
            return Math.Sqrt((pt1.X - pt2.X) * (pt1.X - pt2.X) + (pt1.Y - pt2.Y) * (pt1.Y - pt2.Y));
        }
        //三个点在同一条直线上,输入(X1,Y1),(X2,Y2)以及沿(X2,Y2)侧延长Length,得到的点(X3,Y3)
        public static Yw.Geometry.Point2d GetExtendPointByX(Yw.Geometry.Point2d startPt, Yw.Geometry.Point2d endPt, double exPointX)
        {
            if (startPt == null || endPt == null)
                return null;
            double X1 = startPt.X;
            double Y1 = startPt.Y;
            double X2 = endPt.X;
            double Y2 = endPt.Y;
            if (Math.Abs(X1 - X2) < 0.000001)
            {//竖直
                return null;
            }
            else if (Math.Abs(Y1 - Y2) < 0.000001)
            {//竖直
                return new Yw.Geometry.Point2d(exPointX, Y1);
            }
            else
            {
                //线的形式是 y = k * x + b,
                double k = (Y1 - Y2) / (X1 - X2);
                double b = Y1 - (Y1 - Y2) * X1 / (X1 - X2);
                double Y = k * exPointX + b;
                return new Yw.Geometry.Point2d(exPointX, Y);
            }
        }
        /// <summary>
        /// æ±‚直线外一点到该直线的投影点
        /// </summary>
        /// <param name="pLine">线上任一点</param>
        /// <param name="k">直线斜率</param>
        /// <param name="pOut">线外指定点</param>
        /// <param name="pProject">投影点</param>
        public static Yw.Geometry.Point2d GetProjectivePoint(Yw.Geometry.Point2d pLine, double k, Yw.Geometry.Point2d pOut)
        {
            if (pLine == null || pOut == null)
                return null ;
            Yw.Geometry.Point2d pProject = new Yw.Geometry.Point2d();
            if (k == 0) //垂线斜率不存在情况
            {
                pProject.X = pOut.X;
                pProject.Y = pLine.Y;
            }
            else
            {
                pProject.X = (float)((k * pLine.X + pOut.X / k + pOut.Y - pLine.Y) / (1 / k + k));
                pProject.Y = (float)(-1 / k * (pProject.X - pOut.X) + pOut.Y);
            }
            return pProject;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="pLine1"></param>
        /// <param name="pLine2"></param>
        /// <param name="pOut"></param>
        /// <returns></returns>
        public static  Yw.Geometry.Point2d GetProjectivePoint(Yw.Geometry.Point2d pLine1, Yw.Geometry.Point2d pLine2, Yw.Geometry.Point2d pOut)
        {
            if (pLine1 == null || pLine2 == null || pOut == null)
                return null;
            double k,b;
            GetKandB(pLine1, pLine2, out k, out b);
            if (k >= vertical_k)
            {//垂直
                return new Yw.Geometry.Point2d(pLine1.X, pOut.Y);
            }
            return GetProjectivePoint(pLine1, k, pOut);
        }
        /// <summary>
        /// ç‚¹åˆ°çº¿çš„距离, æ³¨æ„ä¸ä¸€å®šæ˜¯åž‚直距离,点只在(line_start和line_end之间
        /// </summary>
        /// <param name="line_start"></param>
        /// <param name="line_end"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public static double DistancePointToLine(Yw.Geometry.Point2d line_start, Yw.Geometry.Point2d line_end, Yw.Geometry.Point2d point)  // a和b是线段的两个端点, c是检测点
        {
            if (line_start == null || line_end == null || point == null)
                return 0;
            var project_pt = GetProjectivePoint(line_start, line_end, point);
            if (project_pt.X == line_start.X)
            {//垂直
                if (IsInnerPointByY(line_start, line_end, project_pt))
                    return project_pt.Distance(point);
            }
            else
            {
                if (IsInnerPointByX(line_start, line_end, project_pt))
                    return project_pt.Distance(point);
            }
            var dis1 = line_start.Distance(point);
            var dis2 = line_end.Distance(point);
            if (dis1 < dis2)
                return dis1;
            else
                return dis2;
        }
        /// <summary>
        /// ç‚¹åˆ°çº¿çš„距离, æ³¨æ„ä¸ä¸€å®šæ˜¯åž‚直距离,点只在(line_start和line_end之间
        /// </summary>
        /// <param name="line_start"></param>
        /// <param name="line_end"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public static double DistancePointToLine(List<Yw.Geometry.Point2d> multi_line_start,bool isCloseCurve , Yw.Geometry.Point2d point)  // a和b是线段的两个端点, c是检测点
        {
            if (multi_line_start == null || multi_line_start.Count() < 2)
                return -1;
            double min_dis = DistancePointToLine(multi_line_start[0], multi_line_start[1], point);
            for (int index = 1; index < multi_line_start.Count-1; index++)
            {
                var min_dis_current = DistancePointToLine(multi_line_start[index], multi_line_start[index+1], point);
                if (min_dis_current < min_dis)
                {
                    min_dis = min_dis_current;
                }
            }
            if (isCloseCurve)
            {
                var min_dis_current = DistancePointToLine(multi_line_start[0], multi_line_start[multi_line_start.Count - 1], point);
                if (min_dis_current < min_dis)
                {
                    min_dis = min_dis_current;
                }
            }
            return min_dis;
        }
    }
}
WinFrmUI/Yw.WinFrmUI.Phart.Core/Å×ÎïÏß/ParabolaCurveHelper.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,524 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Yw.Geometry
{
    //抛物线 Parabola :  H=K*Q^2 + S (流量扬程线)
    public class ParabolaCurveHelper_H
    {
        //通过点simularPoint和点(0,0)的抛物线,与曲线Curve的交点(没有,返回Point(0,0))
        //曲线公式:H=K*Q^2+S (S就是equipCurveZeroH装置曲线静扬程)
        //equipCurveZeroH是装置曲线的静扬程,当Q=0时的扬程
        public static Yw.Geometry.Point2d GetSectPoint(Yw.Geometry.CubicSpline2d curveExpress, Yw.Geometry.Point2d simularPoint, double equipCurveZeroH)
        {
            if(curveExpress == null)
                return null;
            //if (curveExpress.SplineType == eSpline2dType.)
            //{
            //    var points = Eventech.Common.BezierCurveHelper.GetMultiplyPoints(curveExpress.DefinePoints, 3);
            //    return GetSectPoint(points, simularPoint, equipCurveZeroH);
            //}
            //else
            {
                var points = curveExpress.GetPointListByXRange(curveExpress.MinX, curveExpress.MaxX * 1.2, 50) ;
                return GetSectPoint(points, simularPoint, equipCurveZeroH);
            }
        }
        //
        public static Yw.Geometry.Point2d GetSectPoint(Yw.Geometry.CubicSpline2d curveExpress, Yw.Geometry.Point2d simularPoint, double equipCurveZeroH,
            double ratioExtend)
        {
            if (curveExpress == null)
                return null;
            //if (curveExpress.CurveFitType == Model.eCurveFitType.ThroughPoint)
            //{
            //    if (curveExpress.DefinePoints == null || curveExpress.DefinePoints.Count() < 3)
            //        return null;
            //    var points = Eventech.Common.BezierCurveHelper.GetMultiplyPoints(curveExpress.DefinePoints, 3);
            //    return GetSectPoint(points, simularPoint, equipCurveZeroH);
            //}
            //else
            {
                var points = curveExpress.GetPointListByXRange(curveExpress.MinX, curveExpress.MaxX * ratioExtend, 50);
                return GetSectPoint(points, simularPoint, equipCurveZeroH);
            }
        }
        //通过点simularPoint和点(0,0)的抛物线,与曲线Curve的交点(没有,返回Point(0,0))
        //曲线公式:H=K*Q^2+S (S就是equipCurveZeroH装置曲线静扬程)
        //S是装置曲线的静扬程,当Q=0时的扬程
        public static Yw.Geometry.Point2d GetSectPoint(List<Yw.Geometry.Point2d> CurvePoints, Yw.Geometry.Point2d simularPoint, double equipCurveZeroH)
        {
            Yw.Geometry.Point2d sectPoint = new Yw.Geometry.Point2d(0, 0);
            if (CurvePoints == null || CurvePoints.Count < 2)
                return sectPoint;
            //if (simularPoint.X < CurvePoints.First().X)
            //    return sectPoint;
            //if (DesignPoint.X > CurvePoints.Last().X)
            //    return sectPoint;
            //计算抛物线的K (a)
            if (simularPoint.X < 0.1)
            {//X=0
                return CurvePoints.First();
            }
            if (simularPoint.Y < 0.01)
            {//Y=0
                return CurvePoints.Last();
            }
            double a = (simularPoint.Y - equipCurveZeroH) / (simularPoint.X * simularPoint.X);
            if (a < 0.0001)
                GetSectPointLn(CurvePoints, simularPoint);
            //2点连成直线与抛物线的交点,判断交点是否在2点之间,即可是曲线的交点
            double b, c;
            double delta = 0;
            double x_j1, x_j2;
            for (int i = 0; i < CurvePoints.Count - 1; i++)
            {
                if (Math.Abs(CurvePoints[i].Y - CurvePoints[i + 1].Y) < 0.00001)
                {//水平的
                    x_j1 = Math.Sqrt((CurvePoints[i].Y - equipCurveZeroH) / a);
                    if (IsMiddlePt(CurvePoints[i].X, CurvePoints[i + 1].X, x_j1))
                    {
                        sectPoint.X = x_j1;
                        sectPoint.Y = CurvePoints[i].Y;
                        return sectPoint;
                    }
                }
                else
                {
                    Yw.Geometry.Line2dHelper.GetKandB(CurvePoints[i], CurvePoints[i + 1], out b, out c, 0.0000000001);
                    c = c - equipCurveZeroH;
                    //解方程 ax2-bx-c=0
                    delta = b * b + 4 * a * c;
                    if (delta < 0)
                        continue;
                    x_j1 = (b + Math.Sqrt(delta)) / (2 * a);
                    if (x_j1 >= 0 &&  IsMiddlePt(CurvePoints[i].X, CurvePoints[i + 1].X, x_j1))
                    {
                        sectPoint.X = x_j1;
                        sectPoint.Y = b * x_j1 + c + equipCurveZeroH;
                        return sectPoint;
                    }
                    x_j2 = (b - Math.Sqrt(delta)) / (2 * a);
                    if (x_j2 >= 0 && IsMiddlePt(CurvePoints[i].X, CurvePoints[i + 1].X, x_j2))
                    {
                        sectPoint.X = x_j2;
                        sectPoint.Y = b * x_j2 + c + equipCurveZeroH;
                        return sectPoint;
                    }
                }
            }
            return sectPoint;
        }
        //判断 æ˜¯å¦åœ¨2个数之间
        public static bool IsMiddlePt(double pt1, double pt2, double p)
        {
            if (p > pt1 && p < pt2)
                return true;
            if (p < pt1 && p > pt2)
                return true;
            return false;
        }
        //通过点simularPoint和点(0,0)的抛物线,与曲线Curve的交点(没有,返回Point(0,0)):当流量特别大,H比较小时用
        //曲线公式:H=K*Q^2,然后两边取对数
        protected static Yw.Geometry.Point2d GetSectPointLn(List<Yw.Geometry.Point2d> CurvePoints, Yw.Geometry.Point2d simularPoint)
        {
            Yw.Geometry.Point2d sectPoint = new Yw.Geometry.Point2d(0, 0);
            if (CurvePoints == null || CurvePoints.Count < 2)
                return sectPoint;
            //计算取对数后直线的K
            double a = Math.Log10(simularPoint.Y) / Math.Log10(simularPoint.X);
            if (a < 0.0001)
                return sectPoint;
            //所有的线上的点取对数
            List<Yw.Geometry.Point2d> CurvePointsLn = new List<Yw.Geometry.Point2d>();
            for (int i = 0; i < CurvePoints.Count; i++)
            {
                if (CurvePoints[i].X > 1)//防止第一个点:X=0
                    CurvePointsLn.Add(new Yw.Geometry.Point2d(Math.Log10(CurvePoints[i].X), Math.Log10(CurvePoints[i].Y)));
            }
            //与2点连成直线的交点,判断交点是否在2点之间,即可是曲线的交点
            double b, c;
            double x;
            for (int i = 0; i < CurvePointsLn.Count - 1; i++)
            {
                Yw.Geometry.Line2dHelper.GetKandB(CurvePointsLn[i], CurvePointsLn[i + 1], out  b, out c);
                /*解方程
                 * y=ax
                 * y=bx+c
                 */
                if (Math.Abs(a - b) < 0.001)
                    continue;
                x = c / (a - b);
                if (IsMiddlePt(CurvePointsLn[i].X, CurvePointsLn[i + 1].X, x))
                {
                    sectPoint.X = Math.Pow(10, x);
                    sectPoint.Y = Math.Pow(10, a * x);
                    return sectPoint;
                }
            }
            return sectPoint;
        }
    }
    //抛物线 Parabola :  y = K * Q^2 + B * Q;
    public class ParabolaCurveHelper_E
    {
        //任意两点
        public static bool GetCurvePara(Yw.Geometry.Point2d pt1, Yw.Geometry.Point2d pt2,out double K ,out double B)
        {
            //抛物线拟合 y=ax2+bx;
            double y1 = pt1.Y ;
            double x1 = pt1.X;
            double y2 = pt2.Y;
            double x2 = pt2.X;
            K = (y1 * x2 - y2 * x1) / (x1 * x1 * x2 - x2 * x2 * x1);
            B = (y1 * x2 * x2 - y2 * x1 * x1) / (x1 * x2 * x2 - x2 * x1 * x1);
            return true;
        }
        //工作点和高效点
        public static bool GetCurveParaByBEP(Yw.Geometry.Point2d wrkPt, double bep_q,out double bep_eta, out double K, out double B)
        {
            //抛物线拟合
            //思路 Y=0时, X=0或 -B/K
            //所以 bep_q = -B/K  * 0.5
            K = wrkPt.Y / (wrkPt.X * wrkPt.X - 2 * bep_q * wrkPt.X);
            B = -2 * K * bep_q;
            bep_eta = K * bep_q * bep_q + B * bep_q;
            //if (bep_eta > 0.95)
            //{
            //}
            return true;
        }
    }
    //抛物线 Parabola :  H = K * Q^2   (装置曲线)
    public class ParabolaCurveHelper_Z
    {
        private double _k = 0;
        public double GetK()
        {
            return _k;
        }
        public ParabolaCurveHelper_Z(Yw.Geometry.Point2d pt)
        {
            this._k = pt.Y / pt.X / pt.X;
        }
        public ParabolaCurveHelper_Z(double x, double y)
        {
            this._k =  y / x / x ;
        }
        public double GetY(double x)
        {
            return x * x * this._k;
        }
        public double GetX(double y)
        {
            return Math.Sqrt(y * this._k);
        }
        //计算从x1到x2的弧长
        public double CalcCurveLengthByX(double pt1_x, double pt2_x)
        {
            //思路是从按直线叠加
            double x1 = pt1_x;
            double x2 = pt2_x;
            if (pt1_x > pt2_x)
            {
                x1 = pt2_x;
                x2 = pt1_x;
            }
            double space = (x2 - x1) / 1200;
            double x_last = x1;
            double y_last = GetY(x1);
            double total_length = 0;
            for (int i = 1; i <= 1200; i++ )
            {
                double x = x1 + space * i;
                double y = GetY(x);
                double sub_length = Math.Sqrt((x - x_last) * (x - x_last) + (y - y_last) * (y - y_last));
                x_last = x;
                y_last = y;
                total_length += sub_length;
            }
            return total_length;
        }
        //计算点的位置, x1到x2弧长的摆放路
        public Yw.Geometry.Point2d CalcPointPosiByX(double x1, double x2, double length_ratio)
        {
            if (length_ratio < 0.001)
            {
                return new Yw.Geometry.Point2d(x1, GetY(x1));
            }
            //思路是从按直线叠加
            int point_number = 1800;
            double space = (x2 - x1) / point_number;
            double x_last = x1;
            double y_last = GetY(x1);
            double total_length = 0;
            for (int i = 1; i <= point_number; i++)
            {
                double x = x1 + space * i;
                double y = GetY(x);
                double len = Math.Sqrt((x - x_last) * (x - x_last) + (y - y_last) * (y - y_last));
                x_last = x;
                y_last = y;
                total_length += len;
            }
            double calc_length = total_length * length_ratio;
            double len2 = 0;
            x_last = x1;
            y_last = GetY(x1);
            for (int i = 1; i <= point_number; i++)
            {
                double x = x1 + space * i;
                double y = GetY(x);
                double len = Math.Sqrt((x - x_last) * (x - x_last) + (y - y_last) * (y - y_last));
                x_last = x;
                y_last = y;
                len2 += len;
                if (len2 > calc_length)
                {
                    return new Yw.Geometry.Point2d(x, y);
                }
            }
            return new Yw.Geometry.Point2d(x2,GetY(x2));
        }
        public Yw.Geometry.Point2d CalcPointPosi(Yw.Geometry.Point2d pt1, Yw.Geometry.Point2d pt2, double length_ratio)
        {
            return CalcPointPosiByX(pt1.X, pt2.X, length_ratio);
        }
        //计算点x在弧长(x1->x2)中的百分率
        public double CalcPointRatioByX(double x1, double x2, double x_center )
        {
            double length1 = CalcCurveLengthByX(x1, x2);
            double length2 = CalcCurveLengthByX(x1, x_center);
            return length2 / length1;
        }
        public double CalcPointRatio(Yw.Geometry.Point2d pt1, Yw.Geometry.Point2d pt2, double x_center)
        {
            double length1 = CalcCurveLengthByX(pt1.X, pt2.X);
            double length2 = CalcCurveLengthByX(pt1.X, x_center);
            return length2 / length1;
        }
    }
    //抛物线 Parabola :  H = K * Q^2   (装置曲线) :图表法: æœ‰æ—¶ç”¨QH差别比较大时, ç”¨è·ç¦»è®¡ç®—会有些问题
    public class ParabolaCurveHelper_Z_4Chart
    {
        private double _k = 1;
        private double _chartWidth = 1000;
        private double _chartHeight = 600;
        private double _ratio_scale_x = 1;
        private double _ratio_scale_y = 1;
        private double GetK()
        {//不对外 , å¤–部知道K æ²¡æœ‰æ„ä¹‰
            return _k;
        }
        public ParabolaCurveHelper_Z_4Chart(Yw.Geometry.Point2d pt)
        {
            if (pt == null)
                return;
            this._ratio_scale_x = _chartWidth / pt.X;
            this._ratio_scale_y = _chartHeight / pt.Y;
            this._k = _chartHeight / _chartWidth / _chartWidth;
        }
        public ParabolaCurveHelper_Z_4Chart(double x, double y)
        {
            this._ratio_scale_x = _chartWidth / x;
            this._ratio_scale_y = _chartHeight / y;
            this._k = _chartHeight / _chartWidth / _chartWidth;
        }
        private double GetY_chart(double x)
        {
            return x * x * this._k ;
        }
        private double GetX_chart(double y)
        {
            return Math.Sqrt(y * this._k) ;
        }
        public double GetY(double x)
        {
            double chart_x = x * this._ratio_scale_x;
            var chart_y = chart_x * chart_x * this._k;
            return chart_y / this._ratio_scale_y;
        }
        //计算从x1到x2的弧长(注意时图表上的距离)
        public double CalcCurveLengthByX(double real_x_1, double real_x_2)
        {
            double pt1_x = real_x_1 * this._ratio_scale_x;
            double pt2_x = real_x_2 * this._ratio_scale_x;
            //思路是从按直线叠加
            double x1 = pt1_x;
            double x2 = pt2_x;
            if (pt1_x > pt2_x)
            {
                x1 = pt2_x;
                x2 = pt1_x;
            }
            double space = (x2 - x1) / 1200;
            double x_last = x1;
            double y_last = GetY_chart(x1);
            double total_length = 0;
            for (int i = 1; i <= 1200; i++)
            {
                double x = x1 + space * i;
                double y = GetY_chart(x);
                double sub_length = Math.Sqrt((x - x_last) * (x - x_last) + (y - y_last) * (y - y_last));
                x_last = x;
                y_last = y;
                total_length += sub_length;
            }
            return total_length;
        }
        private Yw.Geometry.Point2d FromChartToReal(double chart_pt_x, double chart_pt_y)
        {
            return new Yw.Geometry.Point2d(chart_pt_x / this._ratio_scale_x, chart_pt_y / this._ratio_scale_y);
        }
        //计算点的位置, x1到x2弧长的摆放路
        public Yw.Geometry.Point2d CalcPointPosiByX(double real_x_1, double real_x_2, double length_ratio)
        {
            double x1 = real_x_1 * this._ratio_scale_x;
            double x2 = real_x_2 * this._ratio_scale_x;
            if (length_ratio < 0.001)
            {
                return FromChartToReal(x1, GetY_chart(x1));
            }
            //思路是从按直线叠加
            int point_number = 1800;
            double space = (x2 - x1) / point_number;
            double x_last = x1;
            double y_last = GetY_chart(x1);
            double total_length = 0;
            for (int i = 1; i <= point_number; i++)
            {
                double x = x1 + space * i;
                double y = GetY_chart(x);
                double len = Math.Sqrt((x - x_last) * (x - x_last) + (y - y_last) * (y - y_last));
                x_last = x;
                y_last = y;
                total_length += len;
            }
            double calc_length = total_length * length_ratio;
            double len2 = 0;
            x_last = x1;
            y_last = GetY_chart(x1);
            for (int i = 1; i <= point_number; i++)
            {
                double x = x1 + space * i;
                double y = GetY_chart(x);
                double len = Math.Sqrt((x - x_last) * (x - x_last) + (y - y_last) * (y - y_last));
                x_last = x;
                y_last = y;
                len2 += len;
                if (len2 > calc_length)
                {
                    return FromChartToReal(x, y);
                }
            }
            return FromChartToReal( x2, GetY_chart(x2));
        }
        public Yw.Geometry.Point2d CalcPointPosi(Yw.Geometry.Point2d pt1, Yw.Geometry.Point2d pt2, double length_ratio)
        {
            return CalcPointPosiByX(pt1.X, pt2.X, length_ratio);
        }
        //计算点x在弧长(x1->x2)中的百分率
        public double CalcPointRatioByX(double x1, double x2, double x_center)
        {
            double length1 = CalcCurveLengthByX(x1, x2);
            double length2 = CalcCurveLengthByX(x1, x_center);
            return length2 / length1;
        }
        public double CalcPointRatio(Yw.Geometry.Point2d pt1, Yw.Geometry.Point2d pt2, double x_center)
        {
            double length1 = CalcCurveLengthByX(pt1.X, pt2.X);
            double length2 = CalcCurveLengthByX(pt1.X, x_center);
            return length2 / length1;
        }
    }
}
WinFrmUI/Yw.WinFrmUI.Phart.Core/×°ÖÃÇúÏß/EquipCurveHelper.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,135 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Yw.Geometry
{
    public class EquipCurveHelper
    {
        /// <summary>
        /// æ ¹æ®æµé‡æ‰¬ç¨‹çº¿,以及给定设计点, è¿”回交点和装置曲线
        /// </summary>
        /// <param name="CurveExpressQH"></param>
        /// <param name="designPoint"></param>
        /// <param name="sectPoint"></param>
        /// <returns></returns>
        static public Yw.Geometry.EquipCurveParas CalcEquipCurve(
             Yw.Geometry.CubicSpline2d CurveExpressQH,
             Yw.Geometry.Point2d designPoint,
             out Yw.Geometry.Point2d sectPoint)
        {
            return CalcEquipCurve(CurveExpressQH, designPoint, 0, false, 11, out sectPoint);
        }
        /// <summary>
        /// æ ¹æ®æµé‡æ‰¬ç¨‹çº¿,以及给定设计点,以及装置曲线0流量时的扬程点, è¿”回交点和装置曲线
        /// </summary>
        /// <param name="CurveExpressQH"></param>
        /// <param name="designPoint"></param>
        /// <param name="equipCurveZeroH"></param>
        /// <param name="sectPoint"></param>
        /// <returns></returns>
        static public Yw.Geometry.EquipCurveParas CalcEquipCurve(
             Yw.Geometry.CubicSpline2d CurveExpressQH,
             Yw.Geometry.Point2d designPoint,
             double equipCurveZeroH,
             out Yw.Geometry.Point2d sectPoint)
        {
            return CalcEquipCurve(CurveExpressQH, designPoint, equipCurveZeroH, false, 11, out sectPoint);
        }
        /// <summary>
        /// æ ¹æ®æµé‡æ‰¬ç¨‹çº¿,以及给定设计点,以及装置曲线0流量时的扬程点, è¿”回交点和装置曲线
        /// </summary>
        /// <param name="CurveExpressQH"></param>
        /// <param name="designPoint"></param>
        /// <param name="equipCurveZeroH"></param>
        /// <param name="isExendCurve"></param>
        /// <param name="fitPointNum"></param>
        /// <param name="sectPoint"></param>
        /// <returns></returns>
        static public Yw.Geometry.EquipCurveParas CalcEquipCurve(
             Yw.Geometry.CubicSpline2d CurveExpressQH,
             Yw.Geometry.Point2d designPoint,
             double equipCurveZeroH,
             bool isExendCurve,//当designPoint超过曲线时, æ˜¯å¦å»¶é•¿è£…置线到designPoint位置
             int fitPointNum,
             out Yw.Geometry.Point2d sectPoint)
        {
            sectPoint = GetSectPoint(CurveExpressQH, designPoint, equipCurveZeroH);
            if (sectPoint == null)
            {
                return null;
            }
            if (isExendCurve)
            {
                Yw.Geometry.Point2d endPt;
                if (sectPoint.X > designPoint.X)
                    endPt = sectPoint;
                else
                    endPt = designPoint;
                //
                return new Yw.Geometry.EquipCurveParas(equipCurveZeroH, endPt, fitPointNum);
            }
            else
            {
                return new Yw.Geometry.EquipCurveParas(equipCurveZeroH, sectPoint, fitPointNum);
            }
        }
        /// <summary>
        /// è®¡ç®—装置曲线与流量扬程曲线的交点
        /// </summary>
        /// <param name="CurveExpressQH"></param>
        /// <param name="designPoint"></param>
        /// <param name="equipCurveZeroH"></param>
        /// <returns></returns>
        static public Yw.Geometry.Point2d GetSectPoint(
            Yw.Geometry.CubicSpline2d CurveExpressQH,
            Yw.Geometry.Point2d designPoint,
            double equipCurveZeroH)
        {//有一种情况: ç”¨åŒ…络法有交点(在最末尾),但用装置曲线绘制时,与装置曲线没有交点,因为交点已超过曲线最大值
            double ratioExtend = 1.15;//CurveExpressQH适当延长一点
            var sectPoint = Yw.Geometry.ParabolaCurveHelper_H.GetSectPoint(CurveExpressQH, designPoint, equipCurveZeroH, ratioExtend);
            if (sectPoint == null)
            {
                return null;
            }
            if (sectPoint.X > CurveExpressQH.MaxX * ratioExtend)
            {
                return null;
            }
            return sectPoint;
        }
        /// <summary>
        /// è®¡ç®—装置曲线与流量扬程曲线的交点
        /// </summary>
        /// <param name="CurveExpressQH"></param>
        /// <param name="DesignPoint"></param>
        /// <param name="equipCurveZeroH"></param>
        /// <param name="ratioExtend"></param>
        /// <returns></returns>
        static public Yw.Geometry.Point2d GetSectPoint(
           Yw.Geometry.CubicSpline2d CurveExpressQH,
           Yw.Geometry.Point2d DesignPoint,
           double equipCurveZeroH,
           double ratioExtend)
        {//有一种情况: ç”¨åŒ…络法有交点(在最末尾),但用装置曲线绘制时,与装置曲线没有交点,因为交点已超过曲线最大值
            var sectPoint = Yw.Geometry.ParabolaCurveHelper_H.GetSectPoint(CurveExpressQH, DesignPoint, equipCurveZeroH, ratioExtend);
            if (sectPoint == null)
            {
                return null;
            }
            if (sectPoint.X > CurveExpressQH.MaxX * ratioExtend)
            {
                return null;
            }
            return sectPoint;
        }
    }
}
WinFrmUI/Yw.WinFrmUI.Phart.Core/×°ÖÃÇúÏß/EquipCurveParas.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,133 @@

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Yw.Geometry
{
    public class EquipCurveParas : ICloneable
    {
        public EquipCurveParas() { }
        //二次曲线
        public EquipCurveParas(double zeroPointH, Yw.Geometry.Point2d endPoint, int fitPointNum=12)
        {
            type = 0;
            SetParabolaPoints(zeroPointH, endPoint);
            ResetCurveInfo(fitPointNum);
        }
        public EquipCurveParas(EquipCurveParas rhs) {
            this.Type = rhs.type;
            this.OriginPoints = rhs.OriginPoints;
            this.CurveInfo = rhs.CurveInfo;
            this.CurveExpress = rhs.CurveExpress;
        }
        //0表示二次曲线, 1表示手动输入
        private int type = 0;
        public int Type { get { return type; } set { type = value; } }
        //手动输入时是输入的点,二次曲线是两个定义点
        private List<Yw.Geometry.Point2d> _originPoints = null;
        public List<Yw.Geometry.Point2d> OriginPoints { get { return _originPoints; } set { _originPoints = value; } }
        //曲线上的点有可能根据坐标最小值,进行了切割
        private List<Yw.Geometry.Point2d> _curveInfo = null;
        public List<Yw.Geometry.Point2d> CurveInfo { get { return _curveInfo; } set { _curveInfo = value; } }
        //曲线方程
        public Yw.Geometry.CubicSpline2d _curveExpress = null;
        public Yw.Geometry.CubicSpline2d CurveExpress { get { return _curveExpress; } set { _curveExpress = value; } }
        //0流量点扬程
        public double ZeroPointH { get { return OriginPoints[0].Y; } }
        //设置抛物线点
        public void SetParabolaPoints(double zeroPointH, Yw.Geometry.Point2d endPoint)
        {
            type = 0;
            this.OriginPoints = new List<Yw.Geometry.Point2d>();
            this.OriginPoints.Add(new Yw.Geometry.Point2d(0, zeroPointH));
            this.OriginPoints.Add(endPoint);
        }
        //
        public void ResetCurveInfo(int fitPointNum)
        {
            if (type != 0)
                return;
            if (OriginPoints == null || OriginPoints.Count != 2)
                return;
            double equipCurveZeroH = OriginPoints[0].Y;
            var endPt = OriginPoints[1];
            List<Yw.Geometry.Point2d> points = new List<Yw.Geometry.Point2d>();
            double k = (endPt.Y - equipCurveZeroH) / (endPt.X * endPt.X);
            double minQ = 0;
            double maxQ = endPt.X;
            double space = (maxQ - minQ) / (fitPointNum - 1);//11个点
            for (int i = 0; i < fitPointNum; i++)
            {
                double x = space * i + minQ;
                double y = k * x * x + equipCurveZeroH;
                points.Add(new Yw.Geometry.Point2d(x, y));
            }
            this.CurveInfo = points;
            this.CurveExpress = new CubicSpline2d(points);
        }
        public double ParabolaCoeff
        {
            get
            {
                if (OriginPoints == null || OriginPoints.Count != 2)
                    return 0;
                double equipCurveZeroH = OriginPoints[0].Y;
                var endPt = OriginPoints[1];
                List<Yw.Geometry.Point2d> points = new List<Yw.Geometry.Point2d>();
                return (endPt.Y - equipCurveZeroH) / (endPt.X * endPt.X);
            }
        }
        public void ResetCurveInfoByMinY(int fitPointNum, double minY)
        {
            if (type != 0)
                return;
            if (minY < 0.01)
            {
                ResetCurveInfo(fitPointNum);
                return;
            }
            if (OriginPoints == null || OriginPoints.Count != 2)
                return;
            double equipCurveZeroH = OriginPoints[0].Y;
            var endPt = OriginPoints[1];
            List<Yw.Geometry.Point2d> points = new List<Yw.Geometry.Point2d>();
            double k = (endPt.Y - equipCurveZeroH) / (endPt.X * endPt.X);
            double minQ = 0;
            if (minY > equipCurveZeroH)
                minQ = Math.Sqrt((minY - equipCurveZeroH) / k);
            double maxQ = endPt.X;
            double space = (maxQ - minQ) / (fitPointNum - 1);
            for (int i = 0; i < fitPointNum; i++)
            {
                double x = space * i + minQ;
                double y = k * x * x + equipCurveZeroH;
                points.Add(new Yw.Geometry.Point2d(x, y));
            }
            this.CurveInfo = points;
        }
        #region Clone
        object ICloneable.Clone()
        {
            return Clone();
        }
        public EquipCurveParas Clone()
        {
            return new EquipCurveParas(this);
        }
        #endregion
    }
}