duheng
2024-11-27 2e3201e1be4247b47b2b8c2a60c56c0d6885b05a
WinFrmUI/Yw.WinFrmUI.Hydro.L3d.Core/01-network/04-link/Pump.cs
@@ -3,17 +3,17 @@
    /// <summary>
    /// 水泵
    /// </summary>
    public abstract class Pump : Link
    public class Pump : Link
    {
        /// <summary>
        /// 线色
        /// </summary>
        public Color? LineColor { get; set; }
        /// <summary>
        /// 线宽
        /// </summary>
        public float? LineWidth { get; set; }
        /// <summary>
        /// 线色
        /// </summary>
        public Color? LineColor { get; set; }
        /// <summary>
        /// 悬停线色
@@ -67,6 +67,135 @@
        //包围盒
        private BoundingBox3d _boundingBox = null;
        //获取包围盒
        private BoundingBox3d GetBoundingBox()
        {
            var lineWidth = this.LineWidth.HasValue ? this.LineWidth.Value : CacheHelper.HydroL3d.Pipe.Line.Width;
            return new BoundingBox3d()
            {
                Min = new Point3d()
                {
                    X = Math.Min(this.StartPosition.X, this.EndPosition.X) - lineWidth / 2f,
                    Y = Math.Min(this.StartPosition.Y, this.EndPosition.Y) - lineWidth / 2f,
                    Z = Math.Min(this.StartPosition.Z, this.EndPosition.Z) - lineWidth / 2f
                },
                Max = new Point3d()
                {
                    X = Math.Max(this.StartPosition.X, this.EndPosition.X) + lineWidth / 2f,
                    Y = Math.Max(this.StartPosition.Y, this.EndPosition.Y) + lineWidth / 2f,
                    Z = Math.Max(this.StartPosition.Z, this.EndPosition.Z) + lineWidth / 2f
                }
            };
        }
        /// <summary>
        /// 绘制
        /// </summary>
        public override void Draw(SharpGL.OpenGL gl)
        {
            _boundingBox = GetBoundingBox();
            if (this.Hovered)
            {
                var lineWidth = this.HoveredLineWidth.HasValue ? this.HoveredLineWidth.Value : CacheHelper.HydroL3d.Pipe.HoveredLine.Width;
                var lineColor = this.HoveredLineColor.HasValue ? this.HoveredLineColor.Value : ColorTranslator.FromHtml(CacheHelper.HydroL3d.Pipe.HoveredLine.Color);
                DrawPipe(gl, lineWidth / 2f, lineColor);
            }
            else if (this.Selected)
            {
                var lineWidth = this.SelectedLineWidth.HasValue ? this.SelectedLineWidth.Value : CacheHelper.HydroL3d.Pipe.SelectedLine.Width;
                var lineColor = this.SelectedLineColor.HasValue ? this.SelectedLineColor.Value : ColorTranslator.FromHtml(CacheHelper.HydroL3d.Pipe.SelectedLine.Color);
                DrawPipe(gl, lineWidth / 2f, lineColor);
            }
            else
            {
                var lineWidth = this.LineWidth.HasValue ? this.LineWidth.Value : CacheHelper.HydroL3d.Pipe.Line.Width;
                var lineColor = this.LineColor.HasValue ? this.LineColor.Value : ColorTranslator.FromHtml(CacheHelper.HydroL3d.Pipe.Line.Color);
                DrawPipe(gl, lineWidth / 2f, lineColor);
            }
        }
        //绘制管道
        private void DrawPipe(SharpGL.OpenGL gl, float radius, Color fillColor)
        {
            gl.Color(fillColor.R / 255.0f, fillColor.G / 255.0f, fillColor.B / 255.0f);
            int slices = 32;  // 管道圆周的分段数,可根据需要修改
            Point3d direction = new Point3d(this.EndPosition - this.StartPosition);
            float length = direction.Length();
            direction.Normalize();
            // 计算旋转轴
            Point3d axis = Point3d.CrossProduct(new Point3d(0, 0, 1), direction);
            if (axis.LengthSquared() < 0.0001f)
            {
                axis = new Point3d(1, 0, 0);
            }
            axis.Normalize();
            float angle = (float)Math.Acos(Point3d.DotProduct(new Point3d(0, 0, 1), direction));
            gl.PushMatrix();
            // 平移到起点
            gl.Translate(this.StartPosition.X, this.StartPosition.Y, this.StartPosition.Z);
            // 绕轴旋转
            gl.Rotate(angle * 180.0f / (float)Math.PI, axis.X, axis.Y, axis.Z);
            // 绘制管道侧面
            gl.Begin(OpenGL.GL_QUAD_STRIP);
            for (int i = 0; i <= slices; i++)
            {
                float theta = (float)i / slices * 2.0f * (float)Math.PI;
                float x = radius * (float)Math.Cos(theta);
                float y = radius * (float)Math.Sin(theta);
                gl.Vertex(x, y, 0.0f);
                gl.Vertex(x, y, length);
            }
            gl.End();
            // 绘制管道两端的圆面
            gl.Begin(OpenGL.GL_POLYGON);
            for (int i = 0; i <= slices; i++)
            {
                float theta = (float)i / slices * 2.0f * (float)Math.PI;
                float x = radius * (float)Math.Cos(theta);
                float y = radius * (float)Math.Sin(theta);
                gl.Vertex(x, y, 0.0f);
            }
            gl.End();
            gl.Begin(OpenGL.GL_POLYGON);
            for (int i = 0; i <= slices; i++)
            {
                float theta = (float)i / slices * 2.0f * (float)Math.PI;
                float x = radius * (float)Math.Cos(theta);
                float y = radius * (float)Math.Sin(theta);
                gl.Vertex(x, y, length);
            }
            gl.End();
            gl.PopMatrix();
        }
        /// <summary>
        /// 包含
        /// </summary>
        public override bool Contains(Point3d pt)
        {
            if (_boundingBox == null)
            {
                return false;
            }
            return _boundingBox.Contains(pt);
        }
    }