983 lines
32 KiB
C#
983 lines
32 KiB
C#
using CoreUnit.Common;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Drawing;
|
||
using System.Text.Json;
|
||
using System.Windows.Forms;
|
||
using System.Xml;
|
||
|
||
namespace CoreUnit.Control.UserControl.Canvas
|
||
{
|
||
public class NodePointLine : INodePoint
|
||
{
|
||
public enum ePoint
|
||
{
|
||
P1,
|
||
P2,
|
||
}
|
||
|
||
static bool m_angleLocked = false;
|
||
Line m_owner;
|
||
Line m_clone;
|
||
|
||
UnitPoint m_originalPoint;
|
||
public UnitPoint OriginalPoint {
|
||
get { lock (this) { return m_originalPoint; } }
|
||
set { lock (this) { m_originalPoint = value; } }
|
||
}
|
||
|
||
UnitPoint m_endPoint;
|
||
public UnitPoint EndPoint {
|
||
get { lock (this) { return m_endPoint; } }
|
||
set { lock (this) { m_endPoint = value; } }
|
||
}
|
||
|
||
ePoint m_pointId;
|
||
public ePoint PointId {
|
||
get { lock (this) { return m_pointId; } }
|
||
set { lock (this) { m_pointId = value; } }
|
||
}
|
||
|
||
public NodePointLine(Line owner, ePoint id)
|
||
{
|
||
m_owner = owner;
|
||
m_clone = m_owner.Clone() as Line;
|
||
m_pointId = id;
|
||
m_originalPoint = GetPoint(m_pointId);
|
||
}
|
||
|
||
#region INodePoint Members
|
||
public IDrawObject GetClone()
|
||
{
|
||
return m_clone;
|
||
}
|
||
|
||
public IDrawObject GetOriginal()
|
||
{
|
||
return m_owner;
|
||
}
|
||
|
||
public void SetPosition(UnitPoint pos)
|
||
{
|
||
if (System.Windows.Forms.Control.ModifierKeys == Keys.Control)
|
||
pos = HitUtil.OrthoPointD(OtherPoint(m_pointId), pos, 45);
|
||
if (m_angleLocked || System.Windows.Forms.Control.ModifierKeys == (Keys)(Keys.Control | Keys.Shift))
|
||
pos = HitUtil.NearestPointOnLine(m_owner.P1, m_owner.P2, pos, true);
|
||
SetPoint(m_pointId, pos, m_clone);
|
||
}
|
||
|
||
public void Finish()
|
||
{
|
||
m_endPoint = GetPoint(m_pointId);
|
||
m_owner.P1 = m_clone.P1;
|
||
m_owner.P2 = m_clone.P2;
|
||
m_clone = null;
|
||
}
|
||
|
||
public void Cancel()
|
||
{
|
||
}
|
||
|
||
public void Undo()
|
||
{
|
||
SetPoint(m_pointId, m_originalPoint, m_owner);
|
||
}
|
||
|
||
public void Redo()
|
||
{
|
||
SetPoint(m_pointId, m_endPoint, m_owner);
|
||
}
|
||
|
||
public void OnKeyDown(ICanvas canvas, KeyEventArgs e)
|
||
{
|
||
if (e.KeyCode == Keys.L) {
|
||
m_angleLocked = !m_angleLocked;
|
||
e.Handled = true;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
protected UnitPoint GetPoint(ePoint pointid)
|
||
{
|
||
if (pointid == ePoint.P1)
|
||
return m_clone.P1;
|
||
if (pointid == ePoint.P2)
|
||
return m_clone.P2;
|
||
return m_owner.P1;
|
||
}
|
||
|
||
protected UnitPoint OtherPoint(ePoint currentpointid)
|
||
{
|
||
if (currentpointid == ePoint.P1)
|
||
return GetPoint(ePoint.P2);
|
||
return GetPoint(ePoint.P1);
|
||
}
|
||
|
||
protected void SetPoint(ePoint pointid, UnitPoint point, Line line)
|
||
{
|
||
if (pointid == ePoint.P1)
|
||
line.P1 = point;
|
||
if (pointid == ePoint.P2)
|
||
line.P2 = point;
|
||
}
|
||
}
|
||
|
||
public class Line : DrawObjectBase, IDrawObject, ISerialize
|
||
{
|
||
UnitPoint m_p1, m_p2;
|
||
|
||
[Browsable(false)]
|
||
public UnitPoint Center {
|
||
get { return new UnitPoint(MiddlePoint); }
|
||
set { MiddlePoint = ((UnitPoint)value).Point; }
|
||
}
|
||
|
||
[Browsable(false)]
|
||
public UnitPoint P1 {
|
||
get { return m_p1; }
|
||
set { m_p1 = value; }
|
||
}
|
||
|
||
[Browsable(false)]
|
||
public UnitPoint P2 {
|
||
get { return m_p2; }
|
||
set { m_p2 = value; }
|
||
}
|
||
|
||
public static string ObjectType {
|
||
get { return "Line"; }
|
||
}
|
||
|
||
public Line()
|
||
{
|
||
}
|
||
|
||
public Line(UnitPoint point, UnitPoint endpoint, float width, Color color)
|
||
{
|
||
P1 = point;
|
||
P2 = endpoint;
|
||
Width = width;
|
||
Color = color;
|
||
Selected = false;
|
||
}
|
||
|
||
public override void InitializeFromModel(UnitPoint point, DrawingLayer layer, ISnapPoint snap)
|
||
{
|
||
P1 = P2 = point;
|
||
Width = layer.Width;
|
||
//Color = layer.Color;
|
||
Selected = true;
|
||
}
|
||
|
||
static int ThresholdPixel = 6;
|
||
static float ThresholdWidth(ICanvas canvas, float objectwidth)
|
||
{
|
||
return ThresholdWidth(canvas, objectwidth, ThresholdPixel);
|
||
}
|
||
|
||
public static float ThresholdWidth(ICanvas canvas, float objectwidth, float pixelwidth)
|
||
{
|
||
double minWidth = canvas.ToUnit(pixelwidth);
|
||
double width = Math.Max(objectwidth / 2, minWidth);
|
||
return (float)width;
|
||
}
|
||
|
||
public virtual void Copy(Line acopy)
|
||
{
|
||
base.Copy(acopy);
|
||
P1 = acopy.P1;
|
||
P2 = acopy.P2;
|
||
Type = acopy.Type;
|
||
m_no = acopy.m_no;
|
||
|
||
//<2F><>ŷ<EFBFBD><C5B7>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD> <20>Ӽ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
ScannerParamNo = acopy.ScannerParamNo;
|
||
Enabled = acopy.Enabled;
|
||
Selected = acopy.Selected;
|
||
WeldingParameterID = acopy.WeldingParameterID;
|
||
|
||
m_objectOffset = acopy.m_objectOffset;
|
||
m_reverse = acopy.m_reverse;
|
||
m_lock = acopy.m_lock;
|
||
|
||
m_tag = acopy.m_tag;
|
||
m_PMU_ID = acopy.m_PMU_ID;
|
||
|
||
m_visionOffset = acopy.m_visionOffset;
|
||
m_alignType = acopy.m_alignType;
|
||
m_alignID = acopy.m_alignID;
|
||
m_alignOffset = acopy.m_alignOffset;
|
||
m_MadebyRCC = acopy.m_MadebyRCC;
|
||
m_RCC_PowerRatio = acopy.m_RCC_PowerRatio;
|
||
}
|
||
|
||
#region IDrawObject Members
|
||
|
||
#region <EFBFBD><EFBFBD>ŷ<EFBFBD><EFBFBD>ü<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>Ӽ<EFBFBD>
|
||
|
||
bool m_enabled = true;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Geometry", 3, 6)]
|
||
[CustomSortedDisplayName("Enable Mark", 6, 6)]
|
||
[Description("Enable Mark")]
|
||
[XmlSerializable]
|
||
public bool Enabled {
|
||
get { return m_enabled; }
|
||
set { m_enabled = value; }
|
||
}
|
||
|
||
bool m_reverse = false;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Geometry", 3, 6)]
|
||
[CustomSortedDisplayName("Reverse", 4, 6)]
|
||
[Description("Reverse")]
|
||
[XmlSerializable]
|
||
public bool Reverse {
|
||
get { return m_reverse; }
|
||
set { m_reverse = value; }
|
||
}
|
||
|
||
bool m_lock = false;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Geometry", 3, 6)]
|
||
[CustomSortedDisplayName("Lock", 5, 6)]
|
||
[Description("Lock")]
|
||
[XmlSerializable]
|
||
public bool Lock {
|
||
get { return m_lock; }
|
||
set { m_lock = value; }
|
||
}
|
||
|
||
bool m_MadebyRCC = false;
|
||
[Browsable(false)]
|
||
[ReadOnly(false)]
|
||
public bool MadebyRCC {
|
||
// RCC <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> object <20><> true <20><> <20>ٲ<EFBFBD><D9B2>ش<EFBFBD>. <20>ڵ峻<DAB5><E5B3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
// Ramping <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD> <20>ʿ<EFBFBD><CABF>ϴ<EFBFBD>.
|
||
get { return m_MadebyRCC; }
|
||
set { m_MadebyRCC = value; }
|
||
}
|
||
|
||
float m_RCC_PowerRatio = 1;
|
||
[Browsable(false)]
|
||
[ReadOnly(false)]
|
||
public float RCC_PowerRatio {
|
||
// RCC <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> object <20><> true <20><> <20>ٲ<EFBFBD><D9B2>ش<EFBFBD>. <20>ڵ峻<DAB5><E5B3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
// Ramping <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD> <20>ʿ<EFBFBD><CABF>ϴ<EFBFBD>.
|
||
get { return m_RCC_PowerRatio; }
|
||
set { m_RCC_PowerRatio = value; }
|
||
}
|
||
|
||
int m_tag = 0;
|
||
[Browsable(false)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Misc", 4, 6)]
|
||
[CustomSortedDisplayName("Tag", 1, 1)]
|
||
[Description("Tag")]
|
||
[XmlSerializable]
|
||
public int Tag {
|
||
get { return m_tag; }
|
||
set { m_tag = value; }
|
||
}
|
||
|
||
int m_PMU_ID = 0;
|
||
[Browsable(false)]
|
||
[ReadOnly(false)]
|
||
[Category("Misc")]
|
||
[DisplayName("PMU_ID")]
|
||
[Description("PMU_ID")]
|
||
[XmlSerializable]
|
||
public int PMU_ID {
|
||
get { return m_PMU_ID; }
|
||
set { m_PMU_ID = value; }
|
||
}
|
||
|
||
int m_scannerParamNo = 0;
|
||
[Browsable(false)]
|
||
[ReadOnly(false)]
|
||
[Category("3. Marking Parameter")]
|
||
[DisplayName("<22><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ȣ")]
|
||
[Description("<22><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>(<28><>ĵ<EFBFBD>ӵ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ŀ<EFBFBD> <20><><EFBFBD><EFBFBD>..) <20><>ȣ <20><><EFBFBD><EFBFBD>")]
|
||
[XmlSerializable]
|
||
public int ScannerParamNo {
|
||
get { return m_scannerParamNo; }
|
||
set { m_scannerParamNo = value; }
|
||
}
|
||
|
||
[Browsable(false)]
|
||
[ReadOnly(false)]
|
||
[Category("3. Marking Parameter")]
|
||
[DisplayName("<22><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ID")]
|
||
[Description("<22><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>(<28><>ĵ<EFBFBD>ӵ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ŀ<EFBFBD> <20><><EFBFBD><EFBFBD>..) ID <20><><EFBFBD><EFBFBD>")]
|
||
[XmlSerializable]
|
||
public int ScannerParamID {
|
||
get { return m_scannerParamNo + 1; }
|
||
set { m_scannerParamNo = value - 1; }
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Pen", 2, 6)]
|
||
[CustomSortedDisplayName("Parameter", 1, 1)]
|
||
[Description("Welding Paramter ID")]
|
||
[Editor(typeof(WeldingParameterIDEditor.WeldingParamterNoUITypeEditor), typeof(System.Drawing.Design.UITypeEditor))]
|
||
[XmlSerializable]
|
||
public WeldingParameterIDEditor.eWeldingParamterID WeldingParameterID {
|
||
get { return (WeldingParameterIDEditor.eWeldingParamterID)ScannerParamID; }
|
||
set { ScannerParamID = (int)value; }
|
||
}
|
||
|
||
PointF m_objectOffset = new PointF();
|
||
[Browsable(false)]
|
||
[ReadOnly(false)]
|
||
[Category("Pen")]
|
||
[DisplayName("Object Offset")]
|
||
[Description("Offset for Shot position when wleding, Expert Use Only")]
|
||
[TypeConverter(typeof(PointFConverter))]
|
||
[XmlSerializable]
|
||
public PointF ObjectOffset {
|
||
get { return m_objectOffset; }
|
||
set { m_objectOffset = value; }
|
||
}
|
||
|
||
PointF m_visionOffset = new PointF();
|
||
[Browsable(false)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Vision Align", 4, 6)]
|
||
[CustomSortedDisplayName("Vision Offset", 4, 4)]
|
||
[Description("Vision Offset")]
|
||
[TypeConverter(typeof(PointFConverter))]
|
||
[XmlSerializable]
|
||
public PointF VisionOffset {
|
||
get { return m_visionOffset; }
|
||
set { m_visionOffset = value; }
|
||
}
|
||
|
||
public enum eAlignType { XY_ANGLE, XY_OFFSET, X_OFFSET, Y_OFFSET, ABSOLUTE_XY }
|
||
|
||
eAlignType m_alignType = eAlignType.ABSOLUTE_XY;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Vision Align", 4, 6)]
|
||
[CustomSortedDisplayName("Align Type", 1, 2)]
|
||
[Description("Align Type")]
|
||
[XmlSerializable]
|
||
public eAlignType AlignType {
|
||
get { return m_alignType; }
|
||
set { m_alignType = value; }
|
||
}
|
||
|
||
int m_alignID = -1;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Vision Align", 4, 6)]
|
||
[CustomSortedDisplayName("Align ID", 2, 2)]
|
||
[Description("Align ID")]
|
||
[XmlSerializable]
|
||
public int AlignID {
|
||
get { return m_alignID; }
|
||
set { m_alignID = value; }
|
||
}
|
||
|
||
PointF m_alignOffset = new PointF();
|
||
[Browsable(false)]
|
||
[ReadOnly(false)]
|
||
[Category("Vision Align")]
|
||
[DisplayName("Align Offset")]
|
||
[Description("Align Offset")]
|
||
[TypeConverter(typeof(PointFConverter))]
|
||
[XmlSerializable]
|
||
public PointF AlignOffset {
|
||
get { return m_alignOffset; }
|
||
set { m_alignOffset = value; }
|
||
}
|
||
#endregion
|
||
|
||
#region <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>ü<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>Ӽ<EFBFBD>
|
||
|
||
int m_no;
|
||
[Browsable(false)]
|
||
[XmlSerializable]
|
||
public int No {
|
||
get { return m_no; }
|
||
set { m_no = value; }
|
||
}
|
||
|
||
[Browsable(false)]
|
||
[ReadOnly(true)]
|
||
[Category("1. <20><>ü")]
|
||
[DisplayName("<22><><EFBFBD><EFBFBD>")]
|
||
[Description("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ü <20><><EFBFBD><EFBFBD>")]
|
||
[XmlSerializable]
|
||
public string Type { get; set; } = Line.ObjectType;
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Geometry", 3, 6)]
|
||
[CustomSortedDisplayName("Start[X,Y](mm)", 1, 6)]
|
||
[Description("Starting Point Of Drawing Object")]
|
||
[TypeConverter(typeof(PointFConverter))]
|
||
[XmlSerializable]
|
||
public PointF PF1 {
|
||
get { lock (this) { return P1.Point; } }
|
||
set { lock (this) { P1 = new UnitPoint(value); } }
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Geometry", 3, 6)]
|
||
[CustomSortedDisplayName("End[X,Y](mm)", 2, 6)]
|
||
[Description("Starting Point Of Drawing Object")]
|
||
[TypeConverter(typeof(PointFConverter))]
|
||
[XmlSerializable]
|
||
public PointF PF2 {
|
||
get { lock (this) { return P2.Point; } }
|
||
set { lock (this) { P2 = new UnitPoint(value); } }
|
||
}
|
||
|
||
[Browsable(false)]
|
||
[ReadOnly(false)]
|
||
[Category("2. Geometry")]
|
||
[DisplayName("3.<2E>߽<EFBFBD><DFBD><EFBFBD>[X,Y](mm)")]
|
||
[Description("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC> <20>߽<EFBFBD><DFBD><EFBFBD>")]
|
||
[TypeConverter(typeof(PointFConverter))]
|
||
public PointF MiddlePoint {
|
||
get { return HitUtil.LineMidpoint(P1, P2).Point; }
|
||
set {
|
||
PointF offset = new PointF();
|
||
offset.X = (value.X - MiddlePoint.X);
|
||
offset.Y = (value.Y - MiddlePoint.Y);
|
||
Move(new UnitPoint(offset));
|
||
}
|
||
}
|
||
|
||
[Browsable(false)]
|
||
[ReadOnly(false)]
|
||
[Category("Geometry")]
|
||
[DisplayName("4.<2E><><EFBFBD><EFBFBD>(<28><>)")]
|
||
[Description("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD>")]
|
||
public float Angle {
|
||
get { return (float)Math.Round(HitUtil.RadiansToDegrees(HitUtil.LineAngleR(P1, P2, 0)), 3); }
|
||
set {
|
||
float angle = value - Angle;
|
||
Rotate(angle, Center);
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(true)]
|
||
[CustomSortedCategory("Boundary", 1, 6)]
|
||
[CustomSortedDisplayName("Left,Bottom,Right,Top", 1, 1)]
|
||
[Description("Boundary of Object")]
|
||
[TypeConverter(typeof(RectangleFConverter))]
|
||
public RectangleF ClientRect {
|
||
get {
|
||
lock (this) { return ScreenUtils.GetRect(P1, P2, 0); }
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Geometry", 3, 6)]
|
||
[CustomSortedDisplayName("Line Length(mm)", 3, 6)]
|
||
[Description("Length of Drawing Object")]
|
||
public double Distance {
|
||
get { return Math.Round(HitUtil.Distance(P1, P2), 3); }
|
||
set {
|
||
double distance = value;
|
||
MakeLength((float)distance);
|
||
}
|
||
}
|
||
|
||
public virtual IDrawObject Clone()
|
||
{
|
||
Line l = new Line();
|
||
l.Copy(this);
|
||
return l;
|
||
}
|
||
|
||
public RectangleF GetBoundingRect(ICanvas canvas)
|
||
{
|
||
float thWidth = ThresholdWidth(canvas, Width);
|
||
return ScreenUtils.GetRect(P1, P2, thWidth);
|
||
}
|
||
|
||
public UnitPoint m_bufferP;
|
||
public void ClearDrawing(ICanvas canvas, RectangleF unitrect)
|
||
{
|
||
Color color = Color.White;
|
||
Pen pen = canvas.CreatePen(color, Width);
|
||
canvas.DrawLine(canvas, pen, P1, P2);
|
||
|
||
if (Highlighted) {
|
||
canvas.DrawLine(canvas, DrawUtils.SelectedPen, P1, P2);
|
||
}
|
||
|
||
if (Selected) {
|
||
canvas.DrawLine(canvas, DrawUtils.SelectedPen, P1, P2);
|
||
|
||
if (P1.IsEmpty == false) {
|
||
DrawUtils.DrawNode(canvas, P1);
|
||
}
|
||
|
||
if (P2.IsEmpty == false) {
|
||
DrawUtils.DrawTriangleNode(canvas, P2);
|
||
}
|
||
}
|
||
}
|
||
|
||
public virtual void Draw(ICanvas canvas, RectangleF unitrect)
|
||
{
|
||
Color color = WeldingParameterIDEditor.weldingColorList[(int)WeldingParameterID - 1];
|
||
Pen pen = canvas.CreatePen(color, Width);
|
||
canvas.DrawLine(canvas, pen, P1, P2);
|
||
DrawUtils.DrawArrowNode(canvas, P2, Angle, pen);
|
||
|
||
if (Highlighted) {
|
||
canvas.DrawLine(canvas, DrawUtils.SelectedPen, P1, P2);
|
||
|
||
}
|
||
|
||
if (Selected) {
|
||
canvas.DrawLine(canvas, DrawUtils.SelectedPen, P1, P2);
|
||
|
||
if (P1.IsEmpty == false) {
|
||
DrawUtils.DrawNode(canvas, P1);
|
||
}
|
||
|
||
if (P2.IsEmpty == false) {
|
||
DrawUtils.DrawTriangleNode(canvas, P2);
|
||
}
|
||
}
|
||
}
|
||
|
||
UnitPoint MidPoint(ICanvas canvas, UnitPoint p1, UnitPoint p2, UnitPoint hitpoint)
|
||
{
|
||
UnitPoint mid = HitUtil.LineMidpoint(p1, p2);
|
||
float thWidth = ThresholdWidth(canvas, Width);
|
||
if (HitUtil.CircleHitPoint(mid, thWidth, hitpoint))
|
||
return mid;
|
||
return UnitPoint.Empty;
|
||
}
|
||
|
||
public bool PointInObject(ICanvas canvas, UnitPoint point)
|
||
{
|
||
float thWidth = ThresholdWidth(canvas, Width);
|
||
return HitUtil.IsPointInLine(P1, P2, point, thWidth);
|
||
}
|
||
|
||
public bool ObjectInRectangle(ICanvas canvas, RectangleF rect, bool anyPoint)
|
||
{
|
||
RectangleF boundingrect = GetBoundingRect(canvas);
|
||
if (anyPoint)
|
||
return HitUtil.LineIntersectWithRect(P1, P2, rect);
|
||
return rect.Contains(boundingrect);
|
||
}
|
||
|
||
public virtual void OnMouseMove(ICanvas canvas, UnitPoint point)
|
||
{
|
||
if (System.Windows.Forms.Control.ModifierKeys == Keys.Control)
|
||
point = HitUtil.OrthoPointD(P1, point, 45);
|
||
P2 = point;
|
||
}
|
||
|
||
public virtual eDrawObjectMouseDown OnMouseDown(ICanvas canvas, UnitPoint point, ISnapPoint snappoint)
|
||
{
|
||
Selected = false;
|
||
if (snappoint is PerpendicularSnapPoint && snappoint.Owner is Line) {
|
||
Line src = snappoint.Owner as Line;
|
||
P2 = HitUtil.NearestPointOnLine(src.P1, src.P2, P1, true);
|
||
return eDrawObjectMouseDown.DoneRepeat;
|
||
}
|
||
if (snappoint is PerpendicularSnapPoint && snappoint.Owner is SnowMan) {
|
||
SnowMan src = snappoint.Owner as SnowMan;
|
||
P2 = HitUtil.NearestPointOnLine(src.P1, src.P2, P1, true);
|
||
return eDrawObjectMouseDown.DoneRepeat;
|
||
}
|
||
if (snappoint is PerpendicularSnapPoint && snappoint.Owner is Dot) {
|
||
Dot src = snappoint.Owner as Dot;
|
||
P2 = HitUtil.NearestPointOnCircle(src.P1, src.Width, P1, 0);
|
||
return eDrawObjectMouseDown.DoneRepeat;
|
||
}
|
||
if (snappoint is PerpendicularSnapPoint && snappoint.Owner is Spline) {
|
||
Spline src = snappoint.Owner as Spline;
|
||
P2 = HitUtil.NearestPointOnCircle(src.Center, src.Radius, P1, 0);
|
||
return eDrawObjectMouseDown.DoneRepeat;
|
||
}
|
||
if (snappoint is PerpendicularSnapPoint && snappoint.Owner is Arc) {
|
||
Arc src = snappoint.Owner as Arc;
|
||
P2 = HitUtil.NearestPointOnCircle(src.Center, src.Radius, P1, 0);
|
||
return eDrawObjectMouseDown.DoneRepeat;
|
||
}
|
||
if (System.Windows.Forms.Control.ModifierKeys == Keys.Control)
|
||
point = HitUtil.OrthoPointD(P1, point, 45);
|
||
P2 = point;
|
||
return eDrawObjectMouseDown.DoneRepeat;
|
||
}
|
||
|
||
public void OnMouseUp(ICanvas canvas, UnitPoint point, ISnapPoint snappoint)
|
||
{
|
||
}
|
||
|
||
public virtual void OnKeyDown(ICanvas canvas, KeyEventArgs e)
|
||
{
|
||
}
|
||
|
||
[Browsable(false)]
|
||
public UnitPoint RepeatStartingPoint {
|
||
get { return P2; }
|
||
}
|
||
|
||
public INodePoint NodePoint(ICanvas canvas, UnitPoint point)
|
||
{
|
||
float thWidth = ThresholdWidth(canvas, Width);
|
||
|
||
if (HitUtil.CircleHitPoint(P1, thWidth, point)) {
|
||
return new NodePointLine(this, NodePointLine.ePoint.P1);
|
||
}
|
||
|
||
if (HitUtil.CircleHitPoint(P2, thWidth, point)) {
|
||
return new NodePointLine(this, NodePointLine.ePoint.P2);
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
public ISnapPoint SnapPoint(ICanvas canvas, UnitPoint point, List<IDrawObject> otherobjs, Type[] runningsnaptypes, Type usersnaptype)
|
||
{
|
||
float thWidth = ThresholdWidth(canvas, Width);
|
||
if (runningsnaptypes != null) {
|
||
foreach (Type snaptype in runningsnaptypes) {
|
||
if (snaptype == typeof(VertextSnapPoint)) {
|
||
if (HitUtil.CircleHitPoint(P1, thWidth, point))
|
||
return new VertextSnapPoint(canvas, this, P1);
|
||
if (HitUtil.CircleHitPoint(P2, thWidth, point))
|
||
return new VertextSnapPoint(canvas, this, P2);
|
||
}
|
||
if (snaptype == typeof(MidpointSnapPoint)) {
|
||
UnitPoint p = MidPoint(canvas, P1, P2, point);
|
||
if (p != UnitPoint.Empty)
|
||
return new MidpointSnapPoint(canvas, this, p);
|
||
}
|
||
if (snaptype == typeof(IntersectSnapPoint)) {
|
||
Line otherline = Utils.FindObjectTypeInList(this, otherobjs, typeof(Line)) as Line;
|
||
if (otherline == null)
|
||
continue;
|
||
UnitPoint p = HitUtil.LinesIntersectPoint(P1, P2, otherline.P1, otherline.P2);
|
||
if (p != UnitPoint.Empty)
|
||
return new IntersectSnapPoint(canvas, this, p);
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
if (usersnaptype == typeof(MidpointSnapPoint))
|
||
return new MidpointSnapPoint(canvas, this, HitUtil.LineMidpoint(P1, P2));
|
||
if (usersnaptype == typeof(IntersectSnapPoint)) {
|
||
Line otherline = Utils.FindObjectTypeInList(this, otherobjs, typeof(Line)) as Line;
|
||
if (otherline == null)
|
||
return null;
|
||
UnitPoint p = HitUtil.LinesIntersectPoint(P1, P2, otherline.P1, otherline.P2);
|
||
if (p != UnitPoint.Empty)
|
||
return new IntersectSnapPoint(canvas, this, p);
|
||
}
|
||
if (usersnaptype == typeof(VertextSnapPoint)) {
|
||
double d1 = HitUtil.Distance(point, P1);
|
||
double d2 = HitUtil.Distance(point, P2);
|
||
if (d1 <= d2)
|
||
return new VertextSnapPoint(canvas, this, P1);
|
||
return new VertextSnapPoint(canvas, this, P2);
|
||
}
|
||
if (usersnaptype == typeof(NearestSnapPoint)) {
|
||
UnitPoint p = HitUtil.NearestPointOnLine(P1, P2, point);
|
||
if (p != UnitPoint.Empty)
|
||
return new NearestSnapPoint(canvas, this, p);
|
||
}
|
||
if (usersnaptype == typeof(PerpendicularSnapPoint)) {
|
||
UnitPoint p = HitUtil.NearestPointOnLine(P1, P2, point);
|
||
if (p != UnitPoint.Empty)
|
||
return new PerpendicularSnapPoint(canvas, this, p);
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public void Move(UnitPoint offset)
|
||
{
|
||
m_p1.X += offset.X;
|
||
m_p1.Y += offset.Y;
|
||
m_p2.X += offset.X;
|
||
m_p2.Y += offset.Y;
|
||
}
|
||
|
||
public void Rotate(float angle, UnitPoint center)
|
||
{
|
||
// UnitPoint mid = Center;
|
||
P1 = HitUtil.RotatePoint(angle, P1, center);
|
||
P2 = HitUtil.RotatePoint(angle, P2, center);
|
||
}
|
||
|
||
public void MakeLength(float distance)
|
||
{
|
||
/*float slope =0;
|
||
double gapX =0;
|
||
double gapY = 0;
|
||
|
||
if (P1.X != P2.X)
|
||
{
|
||
slope = (float)((P2.Y - P1.Y) / (P2.X - P1.X));
|
||
gapX= distance / (2 * Math.Sqrt(Math.Pow(slope, 2) + 1));
|
||
gapY = (distance * slope) / (2 * Math.Sqrt(Math.Pow(slope, 2) + 1));
|
||
}
|
||
else
|
||
{
|
||
gapY = distance * 0.5;
|
||
}
|
||
|
||
PointF pt1 = new PointF();
|
||
PointF pt2 = new PointF();
|
||
|
||
//<2F><><EFBFBD><EFBFBD>-<2D>ȿ<EFBFBD><C8BF><EFBFBD>-161017-<2D><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ȯ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
if(P1.X>P2.X)
|
||
{
|
||
pt1.X = (float)(MiddlePoint.X + gapX);
|
||
pt2.X = (float)(MiddlePoint.X - gapX);
|
||
}
|
||
else
|
||
{
|
||
pt1.X = (float)(MiddlePoint.X - gapX);
|
||
pt2.X = (float)(MiddlePoint.X + gapX);
|
||
}
|
||
|
||
if (P1.Y > P2.Y)
|
||
{
|
||
pt1.Y= (float)(MiddlePoint.Y - gapY);
|
||
pt2.Y = (float)(MiddlePoint.Y + gapY);
|
||
}
|
||
else
|
||
{
|
||
pt1.Y = (float)(MiddlePoint.Y + gapY);
|
||
pt2.Y = (float)(MiddlePoint.Y - gapY);
|
||
}
|
||
|
||
|
||
P1 = new UnitPoint(pt1.X, pt1.Y);
|
||
P2 = new UnitPoint(pt2.X, pt2.Y);
|
||
*/
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||
float x, y;
|
||
double delta;
|
||
|
||
if (P1.X == P2.X) {
|
||
delta = P1.Y < P2.Y ? distance : -distance;
|
||
P2 = new UnitPoint(P2.X, P1.Y + delta);
|
||
} else if (P1.Y == P2.Y) {
|
||
delta = P1.X < P2.X ? distance : -distance;
|
||
P2 = new UnitPoint(P1.X + delta, P2.Y);
|
||
} else {
|
||
float slope = (float)((P2.Y - P1.Y) / (P2.X - P1.X));
|
||
delta = (Math.Sqrt(Math.Pow(distance, 2) / (1 + Math.Pow(slope, 2))));
|
||
|
||
x = (P2.X > P1.X) ? (float)P1.X + (float)delta : (float)P1.X - (float)delta;
|
||
y = (slope * (x - (float)P1.X)) + (float)P1.Y;
|
||
|
||
P2 = new UnitPoint(x, y);
|
||
}
|
||
}
|
||
|
||
public virtual string GetInfoAsString()
|
||
{
|
||
return string.Format("{1:D3} {0}@{2},{3} - L={4:f4} <{5:f4}",
|
||
this.Type,
|
||
No + 1,
|
||
P1.PosAsString(),
|
||
P2.PosAsString(),
|
||
Distance,
|
||
Angle);
|
||
}
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
public void ExtendLineToPoint(UnitPoint newpoint)
|
||
{
|
||
UnitPoint newlinepoint = HitUtil.NearestPointOnLine(P1, P2, newpoint, true);
|
||
if (HitUtil.Distance(newlinepoint, P1) < HitUtil.Distance(newlinepoint, P2))
|
||
P1 = newlinepoint;
|
||
else
|
||
P2 = newlinepoint;
|
||
}
|
||
|
||
#region ISerialize Interface
|
||
public void GetObjectData(XmlWriter wr)
|
||
{
|
||
wr.WriteStartElement(Type);
|
||
Common.XmlUtil.WriteProperties(this, wr);
|
||
wr.WriteEndElement();
|
||
}
|
||
|
||
public virtual string GetObjectData()
|
||
{
|
||
string jsonString = string.Empty;
|
||
var options = new JsonSerializerOptions { WriteIndented = true };
|
||
try {
|
||
jsonString += JsonSerializer.Serialize(this, options);
|
||
} catch {
|
||
|
||
}
|
||
return jsonString;
|
||
}
|
||
|
||
public void AfterSerializedIn()
|
||
{
|
||
|
||
}
|
||
#endregion
|
||
}
|
||
|
||
public class LineEdit : Line, IObjectEditInstance
|
||
{
|
||
protected PerpendicularSnapPoint m_perSnap;
|
||
protected TangentSnapPoint m_tanSnap;
|
||
protected bool m_tanReverse = false;
|
||
protected bool m_singleLineSegment = true;
|
||
|
||
public LineEdit()
|
||
: base()
|
||
{
|
||
}
|
||
|
||
public LineEdit(bool singleLine)
|
||
: base()
|
||
{
|
||
m_singleLineSegment = singleLine;
|
||
if (m_singleLineSegment)
|
||
Type = "Line";
|
||
else
|
||
Type = "PolyLine";
|
||
}
|
||
|
||
public override void InitializeFromModel(UnitPoint point, DrawingLayer layer, ISnapPoint snap)
|
||
{
|
||
base.InitializeFromModel(point, layer, snap);
|
||
m_perSnap = snap as PerpendicularSnapPoint;
|
||
m_tanSnap = snap as TangentSnapPoint;
|
||
}
|
||
|
||
public override void OnMouseMove(ICanvas canvas, UnitPoint point)
|
||
{
|
||
if (m_perSnap != null) {
|
||
MouseMovePerpendicular(canvas, point);
|
||
return;
|
||
}
|
||
if (m_tanSnap != null) {
|
||
MouseMoveTangent(canvas, point);
|
||
return;
|
||
}
|
||
base.OnMouseMove(canvas, point);
|
||
}
|
||
|
||
public override eDrawObjectMouseDown OnMouseDown(ICanvas canvas, UnitPoint point, ISnapPoint snappoint)
|
||
{
|
||
if (m_tanSnap != null && System.Windows.Forms.Control.MouseButtons == MouseButtons.Right) {
|
||
ReverseTangent(canvas);
|
||
return eDrawObjectMouseDown.Continue;
|
||
}
|
||
|
||
if (m_perSnap != null || m_tanSnap != null) {
|
||
if (snappoint != null)
|
||
point = snappoint.SnapPoint;
|
||
OnMouseMove(canvas, point);
|
||
if (m_singleLineSegment)
|
||
return eDrawObjectMouseDown.Done;
|
||
return eDrawObjectMouseDown.DoneRepeat;
|
||
}
|
||
eDrawObjectMouseDown result = base.OnMouseDown(canvas, point, snappoint);
|
||
if (m_singleLineSegment)
|
||
return eDrawObjectMouseDown.Done;
|
||
return eDrawObjectMouseDown.DoneRepeat;
|
||
}
|
||
|
||
public override void OnKeyDown(ICanvas canvas, KeyEventArgs e)
|
||
{
|
||
if (e.KeyCode == Keys.R && m_tanSnap != null) {
|
||
ReverseTangent(canvas);
|
||
e.Handled = true;
|
||
}
|
||
}
|
||
|
||
protected virtual void MouseMovePerpendicular(ICanvas canvas, UnitPoint point)
|
||
{
|
||
if (m_perSnap.Owner is Line) {
|
||
Line src = m_perSnap.Owner as Line;
|
||
P1 = HitUtil.NearestPointOnLine(src.P1, src.P2, point, true);
|
||
P2 = point;
|
||
}
|
||
if (m_perSnap.Owner is SnowMan) {
|
||
SnowMan src = m_perSnap.Owner as SnowMan;
|
||
P1 = HitUtil.NearestPointOnLine(src.P1, src.P2, point, true);
|
||
P2 = point;
|
||
}
|
||
if (m_perSnap.Owner is Dot) {
|
||
Dot src = m_perSnap.Owner as Dot;
|
||
P1 = HitUtil.NearestPointOnCircle(src.P1, src.Width, point, 0);
|
||
P2 = point;
|
||
}
|
||
if (m_perSnap.Owner is Spline) {
|
||
IArc src = m_perSnap.Owner as IArc;
|
||
P1 = HitUtil.NearestPointOnCircle(src.Center, src.Radius, point, 0);
|
||
P2 = point;
|
||
}
|
||
if (m_perSnap.Owner is IArc) {
|
||
IArc src = m_perSnap.Owner as IArc;
|
||
P1 = HitUtil.NearestPointOnCircle(Center, src.Radius, point, 0);
|
||
P2 = point;
|
||
}
|
||
}
|
||
|
||
protected virtual void MouseMoveTangent(ICanvas canvas, UnitPoint point)
|
||
{
|
||
if (m_tanSnap.Owner is IArc) {
|
||
IArc src = m_tanSnap.Owner as IArc;
|
||
P1 = HitUtil.TangentPointOnCircle(Center, src.Radius, point, m_tanReverse);
|
||
P2 = point;
|
||
if (P1 == UnitPoint.Empty)
|
||
P2 = P1 = Center;
|
||
}
|
||
}
|
||
|
||
protected virtual void ReverseTangent(ICanvas canvas)
|
||
{
|
||
m_tanReverse = !m_tanReverse;
|
||
MouseMoveTangent(canvas, P2);
|
||
canvas.Invalidate(false);
|
||
}
|
||
|
||
public void Copy(LineEdit acopy)
|
||
{
|
||
base.Copy(acopy);
|
||
m_perSnap = acopy.m_perSnap;
|
||
m_tanSnap = acopy.m_tanSnap;
|
||
m_tanReverse = acopy.m_tanReverse;
|
||
m_singleLineSegment = acopy.m_singleLineSegment;
|
||
}
|
||
|
||
public override IDrawObject Clone()
|
||
{
|
||
LineEdit l = new LineEdit(false);
|
||
l.Copy(this);
|
||
return l;
|
||
}
|
||
|
||
#region IObjectEditInstance
|
||
public IDrawObject GetDrawObject()
|
||
{
|
||
return new Line(P1, P2, Width, Color) { Type = Type };
|
||
}
|
||
#endregion
|
||
}
|
||
}
|