namespace Yw.WinFrmUI.HydroL3d { /// /// 水池 /// public class Tank : Source { /// /// 长度 /// public float? Length { get; set; } /// /// 宽度 /// public float? Width { get; set; } /// /// 高度 /// public float? Height { get; set; } /// /// 填充颜色 /// public Color? FillColor { get; set; } /// /// 悬停长度 /// public float? HoveredLength { get; set; } /// /// 悬停宽度 /// public float? HoveredWidth { get; set; } /// /// 悬停高度 /// public float? HoveredHeight { get; set; } /// /// 悬停填充颜色 /// public Color? HoveredFillColor { get; set; } /// /// 选择长度 /// public float? SelectedLength { get; set; } /// /// 选择宽度 /// public float? SelectedWidth { get; set; } /// /// 选择高度 /// public float? SelectedHeight { get; set; } /// /// 选择填充颜色 /// public Color? SelectedFillColor { get; set; } //包围盒 private BoundingBox3d _boundingBox = null; //获取包围盒 private BoundingBox3d GetBoundingBox() { var length = this.Length.HasValue ? this.Length.Value : CacheHelper.HydroL3d.Tank.Size.Length; var width = this.Width.HasValue ? this.Width.Value : CacheHelper.HydroL3d.Tank.Size.Width; var height = this.Height.HasValue ? this.Height.Value : CacheHelper.HydroL3d.Tank.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 } }; } /// /// 绘制 /// public override void Draw(SharpGL.OpenGL gl) { _boundingBox = GetBoundingBox(); if (this.Hovered) { var length = this.HoveredLength.HasValue ? this.HoveredLength.Value : CacheHelper.HydroL3d.Tank.HoveredSize.Length; var width = this.HoveredWidth.HasValue ? this.HoveredWidth.Value : CacheHelper.HydroL3d.Tank.HoveredSize.Width; var height = this.HoveredHeight.HasValue ? this.HoveredHeight.Value : CacheHelper.HydroL3d.Tank.HoveredSize.Height; var fillColor = this.HoveredFillColor.HasValue ? this.HoveredFillColor.Value : ColorTranslator.FromHtml(CacheHelper.HydroL3d.Tank.HoveredFill.Color); DrawEllipsoid(gl, length / 2f, width / 2f, height / 2f, fillColor); } else if (this.Selected) { var length = this.SelectedLength.HasValue ? this.SelectedLength.Value : CacheHelper.HydroL3d.Tank.SelectedSize.Length; var width = this.SelectedWidth.HasValue ? this.SelectedWidth.Value : CacheHelper.HydroL3d.Tank.SelectedSize.Width; var height = this.SelectedHeight.HasValue ? this.SelectedHeight.Value : CacheHelper.HydroL3d.Tank.SelectedSize.Height; var fillColor = this.SelectedFillColor.HasValue ? this.SelectedFillColor.Value : ColorTranslator.FromHtml(CacheHelper.HydroL3d.Tank.SelectedFill.Color); DrawEllipsoid(gl, length / 2f, width / 2f, height / 2f, fillColor); } else { var length = this.Length.HasValue ? this.Length.Value : CacheHelper.HydroL3d.Tank.Size.Length; var width = this.Width.HasValue ? this.Width.Value : CacheHelper.HydroL3d.Tank.Size.Width; var height = this.Height.HasValue ? this.Height.Value : CacheHelper.HydroL3d.Tank.Size.Height; var fillColor = this.FillColor.HasValue ? this.FillColor.Value : ColorTranslator.FromHtml(CacheHelper.HydroL3d.Tank.Fill.Color); DrawEllipsoid(gl, length / 2f, width / 2f, height / 2f, fillColor); } } //绘制椭球体 private void DrawEllipsoid(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, fillColor.G, fillColor.B); 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(); } } /// /// 包含 /// public override bool Contains(Point3d pt) { if (_boundingBox == null) { return false; } return _boundingBox.Contains(pt); } } }