namespace Yw.WinFrmUI.HydroL3d
{
///
/// 阀门
///
public class Valve : Link
{
///
/// 线色
///
public Color? LineColor { get; set; }
///
/// 线宽
///
public float? LineWidth { get; set; }
///
/// 悬停线色
///
public Color? HoveredLineColor { get; set; }
///
/// 悬停线宽
///
public float? HoveredLineWidth { get; set; }
///
/// 选择线色
///
public Color? SelectedLineColor { get; set; }
///
/// 选择线宽
///
public float? SelectedLineWidth { get; set; }
///
/// 宽度
///
public float? Width { get; set; }
///
/// 高度
///
public float? Height { get; set; }
///
/// 悬停宽度
///
public float? HoveredWidth { get; set; }
///
/// 悬停高度
///
public float? HoveredHeight { get; set; }
///
/// 选择宽度
///
public float? SelectedWidth { get; set; }
///
/// 选择高度
///
public float? SelectedHeight { 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);
}
}
}