Shuxia Ning
2024-11-19 a01861a95ede48fa4979a47b24f21616e362e534
WinFrmUI/Yw.WinFrmUI.Hydro.L3d.Core/01-network/02-node/Junction.cs
@@ -5,6 +5,10 @@
    /// </summary>
    public class Junction : Node
    {
        /// <summary>
        /// 长度
        /// </summary>
        public float? Length { get; set; }
        /// <summary>
        /// 宽度
@@ -22,6 +26,11 @@
        public Color? FillColor { get; set; }
        /// <summary>
        /// 悬停长度
        /// </summary>
        public float? HoveredLength { get; set; }
        /// <summary>
        /// 悬停宽度
        /// </summary>
        public float? HoveredWidth { get; set; }
@@ -37,6 +46,11 @@
        public Color? HoveredFillColor { get; set; }
        /// <summary>
        /// 选择长度
        /// </summary>
        public float? SelectedLength { get; set; }
        /// <summary>
        /// 选择宽度
        /// </summary>
        public float? SelectedWidth { get; set; }
@@ -51,6 +65,127 @@
        /// </summary>
        public Color? SelectedFillColor { get; set; }
        //包围盒
        private BoundingBox3d _boundingBox = null;
        //获取包围盒
        private BoundingBox3d GetBoundingBox()
        {
            var length = this.Length.HasValue ? this.Length.Value : CacheHelper.HydroL3d.Junction.Size.Length;
            var width = this.Width.HasValue ? this.Width.Value : CacheHelper.HydroL3d.Junction.Size.Width;
            var height = this.Height.HasValue ? this.Height.Value : CacheHelper.HydroL3d.Junction.Size.Height;
            return new BoundingBox3d()
            {
                Min = new Point3d()
                {
                    X = this.Position.X - length / 2f,
                    Y = this.Position.Y - width / 2f,
                    Z = this.Position.Z - height / 2f
                },
                Max = new Point3d()
                {
                    X = this.Position.X + length / 2f,
                    Y = this.Position.Y + width / 2f,
                    Z = this.Position.Z + height / 2f
                }
            };
        }
        /// <summary>
        /// 绘制
        /// </summary>
        public override void Draw(SharpGL.OpenGL gl)
        {
            _boundingBox = GetBoundingBox();
            if (this.Hovered)
            {
                var length = this.HoveredLength.HasValue ? this.HoveredLength.Value : CacheHelper.HydroL3d.Junction.HoveredSize.Length;
                var width = this.HoveredWidth.HasValue ? this.HoveredWidth.Value : CacheHelper.HydroL3d.Junction.HoveredSize.Width;
                var height = this.HoveredHeight.HasValue ? this.HoveredHeight.Value : CacheHelper.HydroL3d.Junction.HoveredSize.Height;
                var fillColor = this.HoveredFillColor.HasValue ? this.HoveredFillColor.Value : ColorTranslator.FromHtml(CacheHelper.HydroL3d.Junction.HoveredFill.Color);
                DrawJunction(gl, length / 2f, width / 2f, height / 2f, fillColor);
            }
            else if (this.Selected)
            {
                var length = this.SelectedLength.HasValue ? this.SelectedLength.Value : CacheHelper.HydroL3d.Junction.SelectedSize.Length;
                var width = this.SelectedWidth.HasValue ? this.SelectedWidth.Value : CacheHelper.HydroL3d.Junction.SelectedSize.Width;
                var height = this.SelectedHeight.HasValue ? this.SelectedHeight.Value : CacheHelper.HydroL3d.Junction.SelectedSize.Height;
                var fillColor = this.SelectedFillColor.HasValue ? this.SelectedFillColor.Value : ColorTranslator.FromHtml(CacheHelper.HydroL3d.Junction.SelectedFill.Color);
                DrawJunction(gl, length / 2f, width / 2f, height / 2f, fillColor);
            }
            else
            {
                var length = this.Length.HasValue ? this.Length.Value : CacheHelper.HydroL3d.Junction.Size.Length;
                var width = this.Width.HasValue ? this.Width.Value : CacheHelper.HydroL3d.Junction.Size.Width;
                var height = this.Height.HasValue ? this.Height.Value : CacheHelper.HydroL3d.Junction.Size.Height;
                var fillColor = this.FillColor.HasValue ? this.FillColor.Value : ColorTranslator.FromHtml(CacheHelper.HydroL3d.Junction.Fill.Color);
                DrawJunction(gl, length / 2f, width / 2f, height / 2f, fillColor);
            }
        }
        //绘制节点
        private void DrawJunction(OpenGL gl, float halfLength, float halfWidth, float halfHeight, Color fillColor)
        {
            const int stacks = 32;
            const int slices = 32;
            // 设置椭球体的中心点坐标
            float x0 = this.Position.X;
            float y0 = this.Position.Y;
            float z0 = this.Position.Z;
            // 设置椭球体的半轴长
            float a = halfLength;
            float b = halfWidth;
            float c = halfHeight;
            gl.Color(fillColor.R / 255f, fillColor.G / 255f, fillColor.B / 255f);
            for (int i = 0; i < stacks; i++)
            {
                float lat0 = ((float)i / (float)stacks - 0.5f) * (float)MathF.PI;
                float z0_ = (float)MathF.Sin(lat0);
                float zr0 = (float)MathF.Cos(lat0);
                float lat1 = ((float)(i + 1) / (float)stacks - 0.5f) * (float)MathF.PI;
                float z1_ = (float)MathF.Sin(lat1);
                float zr1 = (float)MathF.Cos(lat1);
                gl.Begin(SharpGL.OpenGL.GL_TRIANGLE_STRIP);
                for (int j = 0; j <= slices; j++)
                {
                    float lng = ((float)j / (float)slices) * 2.0f * (float)MathF.PI;
                    // 根据椭球体方程计算顶点坐标并加上中心点坐标
                    float x = a * (float)MathF.Cos(lng) * zr0 + x0;
                    float y = b * (float)MathF.Sin(lng) * zr0 + y0;
                    float z = c * z0_ + z0;
                    gl.Color(1.0f, 0.0f, 0.0f);
                    gl.Vertex(x, y, z);
                    x = a * (float)MathF.Cos(lng) * zr1 + x0;
                    y = b * (float)MathF.Sin(lng) * zr1 + y0;
                    z = c * z1_ + z0;
                    gl.Color(1.0f, 0.0f, 0.0f);
                    gl.Vertex(x, y, z);
                }
                gl.End();
            }
        }
        /// <summary>
        /// 包含
        /// </summary>
        public override bool Contains(Point3d pt)
        {
            if (_boundingBox == null)
            {
                return false;
            }
            return _boundingBox.Contains(pt);
        }