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