using DevExpress.CodeParser; using DevExpress.Diagram.Core.Shapes; namespace Yw.WinFrmUI.HydroL3d { /// /// 管道 /// public class Pipe : Link { /// /// 线宽 /// public float? LineWidth { get; set; } /// /// 线色 /// public Color? LineColor { get; set; } /// /// 悬停线色 /// public Color? HoveredLineColor { get; set; } /// /// 悬停线宽 /// public float? HoveredLineWidth { get; set; } /// /// 选择线色 /// public Color? SelectedLineColor { get; set; } /// /// 选择线宽 /// public float? SelectedLineWidth { get; set; } //包围盒 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 } }; } /// /// 绘制 /// 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(); } /// /// 包含 /// public override bool Contains(Point3d pt) { if (_boundingBox == null) { return false; } return _boundingBox.Contains(pt); } } }