using Resources;
using SmartCoalApplication.Annotation.Enum;
using SmartCoalApplication.Base.CommTool;
using SmartCoalApplication.Base.SettingModel;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
/*
* 视场,
* 全部图形构成基于点阵(Points)拟合.
* 图形变换,对外属性均依赖于点阵的换算.
* 点阵集合继承DrawObject 的 pointArrayList 字段
* 全部接口数值皆为原始数值并未进行缩放处理.
*/
namespace SmartCoalApplication.Annotation.FieldView
{
public abstract class ViewBase : DrawObject
{
///
/// 鼠标形状
///
public static Cursor m_rotateCursor = new Cursor(PdnResources.GetResourceStream("Cursors.AnnotationRotateHandle.cur"));
public static Cursor m_resizeCursor = new Cursor(PdnResources.GetResourceStream("Cursors.AnnotationResizeHandle.cur"));
protected MeasureAreaModel measureAreaModel;
#region Points
public virtual List Points
{
get
{
if (pointArrayList == null)
pointArrayList = new List();
return pointArrayList;
}
set
{
pointArrayList = new List();
foreach (var p in value)
{
pointArrayList.Add(p);
}
}
}
public void AddPoint(int x, int y)
{
AddPoint(new PointF(x, y));
}
protected void AddPoint(PointF point)
{
Points.Add(point);
}
public override List GetPoints()
{
return Points;
}
#endregion
#region Bounding Rectangle
public override RectangleF Rectangle
{
get
{
return GetBoundingBox();
}
}
///
/// 外接矩形
///
public override RectangleF GetBoundingBox()
{
int minx = 0, maxx = 0, miny = 0, maxy = 0;
for (int i = 0; i < Points.Count; i++)
{
if (i == 0)
{
minx = maxx = (int)(Points[i].X);
miny = maxy = (int)(Points[i].Y);
}
else
{
if (Points[i].X > maxx) maxx = (int)(Points[i].X);
if (Points[i].X < minx) minx = (int)(Points[i].X);
if (Points[i].Y > maxy) maxy = (int)(Points[i].Y);
if (Points[i].Y < miny) miny = (int)(Points[i].Y);
}
}
return new Rectangle(minx, miny, maxx - minx, maxy - miny);
}
#endregion
#region Draw
///
/// 指定如何组合不同的剪辑区域
/// 用于存储是合并视场、还是剪切视场
///
public CombineMode combineMode;
///
/// Draw rectangle
///
///
public override void Draw(Graphics g)
{
Region reg = g.Clip;
ViewBase view = null;
for (int i = ISurfaceBox.GraphicsList.Count - 1; ;)
{
if (ISurfaceBox.GraphicsList[i].objectType == DrawClass.View)
{
view = (ViewBase)ISurfaceBox.GraphicsList[i];
if (view.combineMode == CombineMode.Union)
{
break;
}
}
i--;
if (i < 0)
{
view.combineMode = CombineMode.Union;
break;
}
}
//获取所有合并的视场
Region union = GetUnionOrDeleteView(CombineMode.Union);
//获取所有删除的视场
Region delete = GetUnionOrDeleteView(CombineMode.Complement);
if (union != null)
{
reg.Xor(union);
}
if (delete != null)
{
reg.Union(delete);
}
SolidBrush sb = new SolidBrush(Color.FromArgb(127, 255, 255, 255));
g.FillRegion(sb, reg);
#region [画边框]
measureAreaModel = ISurfaceBox.GetMeasureAreaModel();
Pen pen = new Pen(Color.FromArgb(measureAreaModel.lineColor), measureAreaModel.lineWidth);
pen.DashStyle = (DashStyle)measureAreaModel.lineStyle;
g.DrawRectangle(pen, new Rectangle((int)view.Rectangle.X, (int)view.Rectangle.Y, (int)view.Rectangle.Width, (int)view.Rectangle.Height));
#endregion
}
///
/// Draw rectangle
///
///
public override void DrawPicture(Graphics g, RectangleF rectangle)
{
#region [画边框]
measureAreaModel = ISurfaceBox.GetMeasureAreaModel();
Pen pen = new Pen(Color.FromArgb(measureAreaModel.lineColor), measureAreaModel.lineWidth);
pen.DashStyle = (DashStyle)measureAreaModel.lineStyle;
g.DrawRectangle(pen, new Rectangle((int)rectangle.X, (int)rectangle.Y, (int)rectangle.Width, (int)rectangle.Height));
#endregion
}
///
/// 获取所有合并或删除的视场
///
///
private Region GetUnionOrDeleteView(CombineMode combineMode)
{
Region region = null;
if (ISurfaceBox.GraphicsList != null && ISurfaceBox.GraphicsList.Count > 0)
{
for (int i = 0; i < ISurfaceBox.GraphicsList.Count; i++)
{
if (ISurfaceBox.GraphicsList[i].objectType == DrawClass.View)
{
ViewBase view = (ViewBase)ISurfaceBox.GraphicsList[i];
GraphicsPath path = new GraphicsPath();
switch (view.drawToolType)
{
case DrawToolType.ViewOval:
case DrawToolType.ViewCircle:
path.AddClosedCurve(ISurfaceBox.GraphicsList[i].GetPoints().ToArray());
break;
case DrawToolType.ViewSquare:
case DrawToolType.ViewRectangle:
case DrawToolType.ViewTriangle:
case DrawToolType.ViewPolygon:
case DrawToolType.ViewTriangleEx:
case DrawToolType.ViewRectangleEx:
if ((ISurfaceBox.GraphicsList[i]).GetPoints().Count > 2)
{
path.AddPolygon((ISurfaceBox.GraphicsList[i]).GetPoints().ToArray());
}
break;
}
if (view.combineMode == combineMode)
{
if (region == null)
region = new Region(path);
else
region.Union(path);
}
}
}
}
return region;
}
public override void DrawTracker(Graphics g)
{
if (!Selected || !canMove)
return;
SolidBrush brush = new SolidBrush(Color.FromArgb(184, Color.Black));
if (Rotatable && Points.Count > 2)
{
for (int i = 1; i <= HandleCount - 1; i++)
{
g.FillRectangle(brush, GetHandleRectangle(i));
}
brush = new SolidBrush(Color.Red);
g.FillEllipse(brush, GetHandleRectangle(HandleCount));
brush.Dispose();
}
else
{
for (int i = 1; i <= HandleCount; i++)
{
g.FillRectangle(brush, GetHandleRectangle(i));
}
}
}
#endregion
#region Rotate
protected PointF _lastPoint;
protected PointF _lastCenter;
protected bool _isRotating;
///
/// 设置可旋转性,用于显示旋转Handle
///
public bool Rotatable = false;
///
/// 图形斜率,用于旋转
///
public double K
{
get;
set;
} = 0;
public virtual void SetK() { }
public virtual PointF Center
{
get
{
var centerX = Rectangle.X + Math.Abs(Rectangle.Width / 2);
var centerY = Rectangle.Y + Math.Abs(Rectangle.Height / 2);
return new PointF(centerX, centerY);
}
set { }
}
protected virtual void StartRotate()
{
_isRotating = true;
_lastCenter = Center;
}
protected virtual void EndRotate()
{
_isRotating = false;
SetK();
}
protected virtual void MoveRotate(PointF point)
{
if (!_isRotating)
{
StartRotate();
_lastPoint = point;
}
double angle = BasicCalculationHelper.CalculateAngle(_lastCenter.X, _lastCenter.Y, _lastPoint.X, _lastPoint.Y, point.X, point.Y);
_lastPoint = point;
for (int i = 0; i < Points.Count; i++)
{
Points[i] = BasicCalculationHelper.GetAnglePoint(Points[i], _lastCenter, angle);
}
}
///
/// 标准化外接矩形
///
public override void Normalize()
{
if (_isRotating)
EndRotate();
}
#endregion
#region Select
///
/// Hit test.
/// Return value: -1 - no hit
/// 0 - hit anywhere
/// > 1 - handle number
///
///
///
public override int HitTest(Point point)
{
if (Selected)
{
for (int i = 1; i <= HandleCount; i++)
{
if (GetHandleRectangle(i).Contains(point))
return i;
}
}
if (PointInObject(point))
return 0;
return -1;
}
protected override bool PointInObject(Point point)
{
int counter = 0;
int i;
double xinters;
PointF p1, p2;
int pointCount = Points.Count;
p1 = Points[0];
for (i = 1; i <= pointCount; i++)
{
p2 = Points[i % pointCount];
if (point.Y > Math.Min(p1.Y, p2.Y)//校验点的Y大于线段端点的最小Y
&& point.Y <= Math.Max(p1.Y, p2.Y))//校验点的Y小于线段端点的最大Y
{
if (point.X <= Math.Max(p1.X, p2.X))//校验点的X小于等线段端点的最大X(使用校验点的左射线判断).
{
if (p1.Y != p2.Y)//线段不平行于X轴
{
xinters = (point.Y - p1.Y) * (p2.X - p1.X) / (p2.Y - p1.Y) + p1.X;
if (p1.X == p2.X || point.X <= xinters)
{
counter++;
}
}
}
}
p1 = p2;
}
return counter % 2 != 0;
}
public override bool IntersectsWith(Rectangle rectangle)
{
return Rectangle.IntersectsWith(rectangle);
}
#endregion
public override void Move(int deltaX, int deltaY)
{
for (int i = 0; i < Points.Count; i++)
{
PointF p = Points[i];
p.X += ISurfaceBox.UnscaleScalar(deltaX);
p.Y += ISurfaceBox.UnscaleScalar(deltaY);
Points[i] = p;
}
OnPropertyChanged();
}
///
/// 获取视场面积
///
///
public virtual double Getacreage()
{
var count = Points.Count;
double area0 = 0;
double area1 = 0;
for (int i = 0; i < count; i++)
{
var x = Points[i].X;
var y = i + 1 < count ? Points[i + 1].Y : Points[0].Y;
area0 += x * y;
x = Points[i].Y;
y = i + 1 < count ? Points[i + 1].X : Points[0].X;
area1 += x * y;
}
return Math.Abs(0.5 * (area0 - area1));
}
}
}