1805 lines
62 KiB
C#
1805 lines
62 KiB
C#
using CoreUnit.Common;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Drawing;
|
||
using System.Text.Json;
|
||
using System.Text.Json.Serialization;
|
||
using System.Windows.Forms;
|
||
using System.Xml;
|
||
|
||
namespace CoreUnit.Control.UserControl.Canvas
|
||
{
|
||
interface IArc
|
||
{
|
||
UnitPoint Center { get; }
|
||
float Radius { get; }
|
||
float StartAngle { get; }
|
||
float EndAngle { get; }
|
||
}
|
||
|
||
class NodePointArcCenter : INodePoint
|
||
{
|
||
protected Arc m_owner;
|
||
protected Arc m_clone;
|
||
protected UnitPoint m_originalPoint;
|
||
protected UnitPoint m_endPoint;
|
||
|
||
public NodePointArcCenter(Arc owner)
|
||
{
|
||
m_owner = owner;
|
||
m_clone = m_owner.Clone() as Arc;
|
||
m_originalPoint = m_owner.Center;
|
||
}
|
||
|
||
#region INodePoint Members
|
||
public IDrawObject GetClone()
|
||
{
|
||
return m_clone;
|
||
}
|
||
|
||
public IDrawObject GetOriginal()
|
||
{
|
||
return m_owner;
|
||
}
|
||
|
||
public virtual void SetPosition(UnitPoint pos)
|
||
{
|
||
m_clone.Center = pos;
|
||
}
|
||
|
||
public virtual void Finish()
|
||
{
|
||
m_endPoint = m_clone.Center;
|
||
m_owner.Center = m_clone.Center;
|
||
m_owner.Radius = m_clone.Radius;
|
||
m_owner.Selected = true;
|
||
m_clone = null;
|
||
}
|
||
|
||
public void Cancel()
|
||
{
|
||
m_owner.Selected = true;
|
||
}
|
||
|
||
public virtual void Undo()
|
||
{
|
||
m_owner.Center = m_originalPoint;
|
||
}
|
||
|
||
public virtual void Redo()
|
||
{
|
||
m_owner.Center = m_endPoint;
|
||
}
|
||
|
||
public void OnKeyDown(ICanvas canvas, KeyEventArgs e)
|
||
{
|
||
}
|
||
#endregion
|
||
}
|
||
|
||
class NodePointArcRadius : INodePoint
|
||
{
|
||
protected Arc m_owner;
|
||
protected Arc m_clone;
|
||
protected float m_originalValue;
|
||
protected float m_endValue;
|
||
|
||
public NodePointArcRadius(Arc owner)
|
||
{
|
||
m_owner = owner;
|
||
m_clone = m_owner.Clone() as Arc;
|
||
m_clone.CurrentPoint = m_owner.CurrentPoint;
|
||
m_originalValue = m_owner.Radius;
|
||
}
|
||
|
||
#region INodePoint Members
|
||
public IDrawObject GetClone()
|
||
{
|
||
return m_clone;
|
||
}
|
||
|
||
public IDrawObject GetOriginal()
|
||
{
|
||
return m_owner;
|
||
}
|
||
|
||
public virtual void SetPosition(UnitPoint pos)
|
||
{
|
||
m_clone.OnMouseMove(null, pos);
|
||
}
|
||
|
||
public virtual void Finish()
|
||
{
|
||
m_endValue = m_clone.Radius;
|
||
m_owner.Radius = m_clone.Radius;
|
||
m_owner.Selected = true;
|
||
m_clone = null;
|
||
}
|
||
|
||
public void Cancel()
|
||
{
|
||
m_owner.Selected = true;
|
||
}
|
||
|
||
public virtual void Undo()
|
||
{
|
||
m_owner.Radius = m_originalValue;
|
||
}
|
||
|
||
public virtual void Redo()
|
||
{
|
||
m_owner.Radius = m_endValue;
|
||
}
|
||
|
||
public void OnKeyDown(ICanvas canvas, KeyEventArgs e)
|
||
{
|
||
}
|
||
#endregion
|
||
}
|
||
|
||
class NodePointArcAngle : INodePoint
|
||
{
|
||
protected Arc m_owner;
|
||
protected Arc m_clone;
|
||
protected float m_originalA1;
|
||
protected float m_endA1;
|
||
protected float m_originalA2;
|
||
protected float m_endA2;
|
||
|
||
public NodePointArcAngle(Arc owner)
|
||
{
|
||
m_owner = owner;
|
||
m_clone = m_owner.Clone() as Arc;
|
||
m_clone.CurrentPoint = m_owner.CurrentPoint;
|
||
m_originalA1 = m_owner.StartAngle;
|
||
m_originalA2 = m_owner.EndAngle;
|
||
m_owner.Selected = false;
|
||
}
|
||
|
||
#region INodePoint Members
|
||
public IDrawObject GetClone()
|
||
{
|
||
return m_clone;
|
||
}
|
||
|
||
public IDrawObject GetOriginal()
|
||
{
|
||
return m_owner;
|
||
}
|
||
|
||
public virtual void SetPosition(UnitPoint pos)
|
||
{
|
||
// Node<64><65> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>쿡 drawingMode<64><65> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
m_clone.drawingNodeSet = true;
|
||
m_clone.OnMouseMove(null, pos);
|
||
}
|
||
|
||
public virtual void Finish()
|
||
{
|
||
m_endA1 = m_clone.StartAngle;
|
||
m_endA2 = m_clone.EndAngle;
|
||
m_owner.Copy(m_clone);
|
||
// Node<64><65> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ϸ<EFBFBD><CFB7><EFBFBD> <20><><EFBFBD>쿡<EFBFBD><ECBFA1> SweepAngle<6C><65> EndAngle - StartAngle <20><><EFBFBD><EFBFBD>.
|
||
m_owner.SweepAngle = m_clone.EndAngle - m_clone.StartAngle;
|
||
m_clone = null;
|
||
}
|
||
|
||
public void Cancel()
|
||
{
|
||
m_owner.Selected = true;
|
||
}
|
||
|
||
public virtual void Undo()
|
||
{
|
||
m_owner.StartAngle = m_originalA1;
|
||
m_owner.EndAngle = m_originalA2;
|
||
}
|
||
|
||
public virtual void Redo()
|
||
{
|
||
m_owner.StartAngle = m_endA1;
|
||
m_owner.EndAngle = m_endA2;
|
||
}
|
||
|
||
public void OnKeyDown(ICanvas canvas, KeyEventArgs e)
|
||
{
|
||
}
|
||
#endregion
|
||
}
|
||
|
||
public class Arc : DrawObjectBase, IArc, IDrawObject, ISerialize
|
||
{
|
||
public const int FLAG_INNER_ARC = 7123;
|
||
public enum eDirection
|
||
{
|
||
CW,
|
||
CCW,
|
||
}
|
||
|
||
UnitPoint m_center;
|
||
float m_radius;
|
||
float m_startAngle = 0;
|
||
float m_endAngle = 0;
|
||
float m_absSweepAngle = 0;
|
||
float m_sweepAngle = 0;
|
||
float m_length = 0;
|
||
|
||
private List<IDrawObject> _hatchObjects = new List<IDrawObject>();
|
||
public List<IDrawObject> GetHatchObjects()
|
||
{
|
||
return _hatchObjects;
|
||
}
|
||
|
||
eDirection m_direction = eDirection.CCW;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Geometry", 3, 6)]
|
||
[CustomSortedDisplayName("Direction", 6, 8)]
|
||
[Description("unit : CW(ClockWise) / CCW(CounterClockWise)")]
|
||
[XmlSerializable]
|
||
public eDirection Direction {
|
||
get { return m_direction; }
|
||
set {
|
||
eDirection beforeDirection = m_direction;
|
||
m_direction = value;
|
||
|
||
if (beforeDirection != value) {
|
||
if ((m_direction == eDirection.CCW && SweepAngle < 0) || (m_direction == eDirection.CW && SweepAngle > 0)) {
|
||
SweepAngle = -1 * SweepAngle;
|
||
}
|
||
if (m_useHatching && !_isLoading) {
|
||
GenerateHatch();
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
bool m_reverse = false;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Geometry", 3, 6)]
|
||
[CustomSortedDisplayName("Reverse", 6, 8)]
|
||
[Description("Reverse")]
|
||
[XmlSerializable]
|
||
public bool Reverse {
|
||
get { return m_reverse; }
|
||
set { m_reverse = value; }
|
||
}
|
||
|
||
public static string ObjectType {
|
||
get { return "Arc"; }
|
||
}
|
||
|
||
public Arc()
|
||
{
|
||
}
|
||
|
||
public Arc(eArcType type)
|
||
{
|
||
m_arcType = type;
|
||
m_curPoint = eCurrentPoint.p1;
|
||
if (m_arcType == eArcType.typeCenterRadius)
|
||
m_curPoint = eCurrentPoint.center;
|
||
}
|
||
|
||
public override void InitializeFromModel(UnitPoint point, DrawingLayer layer, ISnapPoint snap)
|
||
{
|
||
Width = layer.Width;
|
||
Color = layer.Color;
|
||
OnMouseDown(null, point, snap);
|
||
Selected = true;
|
||
_isLoading = false;
|
||
}
|
||
|
||
public void Copy(Arc acopy)
|
||
{
|
||
base.Copy(acopy);
|
||
|
||
// Hatching <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
_isLoading = true;
|
||
|
||
// <20><> <20>κ<EFBFBD><CEBA><EFBFBD> Clone <20><> Ȱ<><C8B0><EFBFBD>Ǵ<EFBFBD> <20>κ<EFBFBD><CEBA><EFBFBD>.
|
||
// Direction<6F><6E> <20><><EFBFBD><EFBFBD>, StartAngle/EndAngle<6C><65> <20><><EFBFBD><EFBFBD> <20><EFBFBD><DEB6><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>ʱ<EFBFBD>ȭ<EFBFBD><C8AD>. __ 210526 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
Direction = acopy.Direction;
|
||
|
||
Center = acopy.Center;
|
||
Radius = acopy.Radius;
|
||
// EndAngle <20><> StartAngle<6C><65> <20><><EFBFBD><EFBFBD> SweepAngle<6C><65> <20><><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD> SweepAngle<6C><65> <20><> ó<><C3B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʿ<EFBFBD>
|
||
SweepAngle = acopy.SweepAngle;
|
||
StartAngle = acopy.StartAngle;
|
||
EndAngle = acopy.EndAngle;
|
||
Selected = acopy.Selected;
|
||
Direction = acopy.Direction;
|
||
m_arcType = acopy.m_arcType;
|
||
m_curPoint = acopy.m_curPoint;
|
||
|
||
Type = acopy.Type;
|
||
m_no = acopy.m_no;
|
||
|
||
ScannerParamNo = acopy.ScannerParamNo;
|
||
Enabled = acopy.Enabled;
|
||
WeldingParameterID = acopy.WeldingParameterID;
|
||
|
||
m_reverse = acopy.m_reverse;
|
||
m_lock = acopy.m_lock;
|
||
m_RCCArc = acopy.m_RCCArc;
|
||
m_MadebyRCC = acopy.m_MadebyRCC;
|
||
m_RCC_PowerRatio = acopy.m_RCC_PowerRatio;
|
||
|
||
// Hatching <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
m_useHatching = acopy.m_useHatching;
|
||
m_hatchFillingType = acopy.m_hatchFillingType;
|
||
m_hatchMarkType = acopy.m_hatchMarkType;
|
||
m_hatchLineDir = acopy.m_hatchLineDir;
|
||
m_hatchinnerradius = acopy.m_hatchinnerradius;
|
||
m_hatchmarjin = acopy.m_hatchmarjin;
|
||
m_hatchInterval = acopy.m_hatchInterval;
|
||
|
||
_isLoading = false;
|
||
if (m_useHatching) {
|
||
GenerateHatch();
|
||
}
|
||
|
||
}
|
||
|
||
#region IDrawObject Members
|
||
|
||
#region <EFBFBD><EFBFBD>ŷ<EFBFBD><EFBFBD>ü<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>Ӽ<EFBFBD>
|
||
[Browsable(true)]
|
||
[ReadOnly(true)]
|
||
[CustomSortedCategory("Boundary", 1, 6)]
|
||
[CustomSortedDisplayName("<22><>Left,Bottom,<2C><>Right,Top", 1, 1)]
|
||
[Description("Boundary of Object")]
|
||
[TypeConverter(typeof(RectangleFConverter))]
|
||
public RectangleF ClientRect {
|
||
get {
|
||
List<UnitPoint> RectanglePoint = new List<UnitPoint>();
|
||
|
||
// 360<36><30> <20>̻<EFBFBD><CCBB><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʾҾ<CABE><D2BE><EFBFBD>.
|
||
if (Math.Abs(SweepAngle) >= 360) {
|
||
RectanglePoint.Add(new UnitPoint(Center.X - Radius, Center.Y + Radius));
|
||
RectanglePoint.Add(new UnitPoint(Center.X - Radius, Center.Y - Radius));
|
||
RectanglePoint.Add(new UnitPoint(Center.X + Radius, Center.Y + Radius));
|
||
RectanglePoint.Add(new UnitPoint(Center.X + Radius, Center.Y - Radius));
|
||
|
||
return ScreenUtils.GetRect(RectanglePoint, 0);
|
||
}
|
||
|
||
RectanglePoint.Add(StartAnglePoint);
|
||
RectanglePoint.Add(EndAnglePoint);
|
||
|
||
int[] dx = new int[] { 0, -1, 0, 1 };
|
||
int[] dy = new int[] { 1, 0, -1, 0 };
|
||
|
||
int startQuad, endQuad;
|
||
|
||
if (StartAngle >= 0) startQuad = (int)StartAngle / 90;
|
||
else startQuad = (int)((StartAngle + 360) / 90);
|
||
|
||
if (EndAngle >= 0) endQuad = (int)EndAngle / 90;
|
||
else endQuad = (int)((EndAngle + 360) / 90);
|
||
|
||
int iter = 0, dir = 0;
|
||
int positiveNumberVariable = 0;
|
||
|
||
|
||
if (startQuad != endQuad) {
|
||
if (Direction == eDirection.CCW) {
|
||
if (startQuad > endQuad) iter = endQuad - startQuad + 4;
|
||
else iter = endQuad - startQuad;
|
||
dir = 1;
|
||
positiveNumberVariable = 4;
|
||
}
|
||
if (Direction == eDirection.CW) {
|
||
if (startQuad < endQuad) iter = -endQuad + startQuad + 4;
|
||
else iter = -endQuad + startQuad;
|
||
dir = -1;
|
||
positiveNumberVariable = 3;
|
||
}
|
||
|
||
for (int i = 0; i < iter; i++) {
|
||
int index = (startQuad + dir * i + positiveNumberVariable) % 4;
|
||
if (index < 0) index += 4; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ
|
||
|
||
float xAxis = (float)(Center.X) + Radius * dx[index];
|
||
float yAxis = (float)(Center.Y) + Radius * dy[index];
|
||
RectanglePoint.Add(new UnitPoint(xAxis, yAxis));
|
||
}
|
||
}
|
||
|
||
return ScreenUtils.GetRect(RectanglePoint, 0);
|
||
//lock (this) { return ScreenUtils.GetRect(Center, Radius, 0); }
|
||
}
|
||
}
|
||
|
||
bool m_enabled = true;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Geometry", 3, 6)] // <20><><EFBFBD><EFBFBD> <20>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD>
|
||
[CustomSortedDisplayName("Enable Mark", 8, 8)] // <20><><EFBFBD><EFBFBD> <20>۾<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
[Description("Enable Mark")] // <20><><EFBFBD><EFBFBD> <20>۾<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
[XmlSerializable]
|
||
public bool Enabled {
|
||
get { return m_enabled; }
|
||
set { m_enabled = value; }
|
||
}
|
||
|
||
bool m_lock = false;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Geometry", 3, 6)]
|
||
[CustomSortedDisplayName("Lock", 7, 8)]
|
||
[Description("Lock")]
|
||
[XmlSerializable]
|
||
public bool Lock {
|
||
get { return m_lock; }
|
||
set { m_lock = value; }
|
||
}
|
||
|
||
bool m_RCCArc = false;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Geometry", 3, 6)]
|
||
[CustomSortedDisplayName("RCC Mode", 9, 8)]
|
||
[Description("RCC Arc Mode")]
|
||
[XmlSerializable]
|
||
public bool RCCArc {
|
||
get { return m_RCCArc; }
|
||
set { m_RCCArc = 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_scannerParamNo = 0;
|
||
[Browsable(false)]
|
||
[ReadOnly(false)]
|
||
[Category("<22><><EFBFBD><EFBFBD> <20>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD>")]
|
||
[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("<22><><EFBFBD><EFBFBD> <20>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD>")]
|
||
[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 ID", 2, 2)]
|
||
[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; }
|
||
}
|
||
|
||
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", 5, 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", 5, 6)]
|
||
[CustomSortedDisplayName("Align ID", 2, 2)]
|
||
[Description("Align ID")]
|
||
[XmlSerializable]
|
||
public int AlignID {
|
||
get { return m_alignID; }
|
||
set { m_alignID = value; }
|
||
}
|
||
|
||
// Hatching <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
[Browsable(false)]
|
||
private bool _isLoading = true;
|
||
|
||
int m_innerarcflag = 0;
|
||
[Browsable(false)]
|
||
[XmlSerializable]
|
||
public int InnerArcFlag {
|
||
get { return m_innerarcflag; }
|
||
set { m_innerarcflag = value; }
|
||
}
|
||
|
||
bool m_useHatching = false;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("Hatching Option")]
|
||
[DisplayName("Use Hatching")]
|
||
[Description("<22><>Ī <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ȱ<><C8B0>ȭ<EFBFBD>մϴ<D5B4>.")]
|
||
[XmlSerializable]
|
||
public bool UseHatching {
|
||
get { return m_useHatching; }
|
||
set {
|
||
m_useHatching = value;
|
||
GenerateHatch();
|
||
}
|
||
}
|
||
|
||
public enum eHatchFillingType { Filling_Lines, Filling_Arcs }
|
||
eHatchFillingType m_hatchFillingType = eHatchFillingType.Filling_Lines;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("Hatching Option")]
|
||
[DisplayName("Filling Type")]
|
||
[Description("ä<><C3A4><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD> / <20><><EFBFBD>ɿ<EFBFBD>)")]
|
||
[XmlSerializable]
|
||
public eHatchFillingType HatchFillingType {
|
||
get { return m_hatchFillingType; }
|
||
set {
|
||
m_hatchFillingType = value;
|
||
|
||
if (m_useHatching) {
|
||
GenerateHatch();
|
||
}
|
||
}
|
||
}
|
||
|
||
public enum eHatchMarkType { Outline_and_Hatch, Hatch_and_Outline, Hatch_Only }
|
||
eHatchMarkType m_hatchMarkType = eHatchMarkType.Outline_and_Hatch;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("Hatching Option")]
|
||
[DisplayName("Mark Order")]
|
||
[Description("<22><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>")]
|
||
[XmlSerializable]
|
||
public eHatchMarkType HatchMarkType {
|
||
get { return m_hatchMarkType; }
|
||
set { m_hatchMarkType = value; }
|
||
}
|
||
|
||
public enum eHatchLineDir { ZigZag, LeftToRight, RightToLeft }
|
||
eHatchLineDir m_hatchLineDir = eHatchLineDir.ZigZag;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("Hatching Option")]
|
||
[DisplayName("Line Direction")]
|
||
[Description("<22><>Ī <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>. (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F>ܹ<EFBFBD><DCB9><EFBFBD>)")]
|
||
[XmlSerializable]
|
||
public eHatchLineDir HatchLineDir {
|
||
get { return m_hatchLineDir; }
|
||
set {
|
||
m_hatchLineDir = value;
|
||
if (m_useHatching) GenerateHatch();
|
||
}
|
||
}
|
||
|
||
float m_hatchinnerradius = 0;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("Hatching Option")]
|
||
[DisplayName("Inner Radius(mm)")]
|
||
[Description("<22><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (0<≯<EFBFBD> <20><> ä<><C3A4>)")]
|
||
[XmlSerializable]
|
||
public float HatchInnerRadius {
|
||
get { return m_hatchinnerradius; }
|
||
set {
|
||
if (_isLoading) {
|
||
m_hatchinnerradius = value;
|
||
return;
|
||
}
|
||
|
||
if (value < 0) {
|
||
return;
|
||
}
|
||
|
||
if (value >= Radius) {
|
||
return;
|
||
}
|
||
|
||
m_hatchinnerradius = value;
|
||
|
||
if (m_useHatching) {
|
||
GenerateHatch();
|
||
}
|
||
}
|
||
}
|
||
|
||
float m_hatchmarjin = 0;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("Hatching Option")]
|
||
[DisplayName("Margin(mm)")]
|
||
[Description("<22>ܰ<EFBFBD><DCB0><EFBFBD><EFBFBD><EFBFBD> <20><>Ī <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>")]
|
||
[XmlSerializable]
|
||
public float HatchMarjin {
|
||
get { return m_hatchmarjin; }
|
||
set {
|
||
if (value < 0) {
|
||
return;
|
||
}
|
||
|
||
m_hatchmarjin = value;
|
||
|
||
if (m_useHatching) {
|
||
GenerateHatch();
|
||
}
|
||
}
|
||
}
|
||
|
||
float m_hatchInterval = 1.0f;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("Hatching Option")]
|
||
[DisplayName("Interval(mm)")]
|
||
[Description("<22><>Ī <20><><EFBFBD><EFBFBD>")]
|
||
[XmlSerializable]
|
||
public float HatchInterval {
|
||
get { return m_hatchInterval; }
|
||
set {
|
||
if (value <= 0) {
|
||
return;
|
||
}
|
||
|
||
m_hatchInterval = value;
|
||
|
||
if (m_useHatching) {
|
||
GenerateHatch();
|
||
}
|
||
}
|
||
}
|
||
#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; }
|
||
}
|
||
|
||
string m_type;
|
||
[Browsable(false)]
|
||
[ReadOnly(true)]
|
||
[Category("<22><>ü")]
|
||
[DisplayName("<22><><EFBFBD><EFBFBD>")]
|
||
[Description("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ü <20><><EFBFBD><EFBFBD>")]
|
||
[XmlSerializable]
|
||
public string Type {
|
||
get {
|
||
m_type = Arc.ObjectType;
|
||
return m_type;
|
||
}
|
||
|
||
set { m_type = value; }
|
||
}
|
||
|
||
[Browsable(false)]
|
||
[ReadOnly(false)]
|
||
[JsonIgnore]
|
||
public UnitPoint Center {
|
||
get { return m_center; }
|
||
set {
|
||
m_center = value;
|
||
m_lastPoint = m_center;
|
||
if (m_useHatching && !_isLoading) {
|
||
GenerateHatch();
|
||
}
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Geometry", 3, 6)]
|
||
[CustomSortedDisplayName("Center[X,Y](mm)", 1, 8)]
|
||
[Description("Center Of Drawing Object")]
|
||
[TypeConverter(typeof(PointFConverter))]
|
||
[XmlSerializable]
|
||
public PointF CenterPointF {
|
||
get { lock (this) { return Center.Point; } }
|
||
set { lock (this) { Center = new UnitPoint(value); } }
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Geometry", 3, 6)]
|
||
[CustomSortedDisplayName("Radius", 2, 8)]
|
||
[Description("Radius Of Arc")]
|
||
[JsonIgnore]
|
||
public float Radius {
|
||
get { return m_radius; }
|
||
set {
|
||
m_radius = value;
|
||
if (m_useHatching && !_isLoading) {
|
||
GenerateHatch();
|
||
}
|
||
}
|
||
}
|
||
|
||
[Browsable(false)]
|
||
[ReadOnly(false)]
|
||
[JsonIgnore]
|
||
public PointF MiddlePoint {
|
||
get { return m_center.Point; }
|
||
set { m_center = new UnitPoint(value); }
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Geometry", 3, 6)]
|
||
[CustomSortedDisplayName("Start Angle", 3, 8)]
|
||
[Description("Start Angle")]
|
||
[JsonIgnore]
|
||
public float StartAngle {
|
||
get {
|
||
return m_startAngle;
|
||
}
|
||
set {
|
||
m_startAngle = value;
|
||
|
||
while (0 > m_startAngle) {
|
||
m_startAngle += 360;
|
||
}
|
||
while (m_startAngle >= 360) {
|
||
m_startAngle -= 360;
|
||
}
|
||
if (drawingNodeSet) {
|
||
// <20><EFBFBD><D7B8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> / <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>迡 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>ȭ <20>ʿ<EFBFBD>
|
||
if (Direction == eDirection.CCW) {
|
||
if (EndAngle < StartAngle) m_endAngle += 360;
|
||
else if (EndAngle > StartAngle + 360) m_endAngle -= 360;
|
||
else;
|
||
} else if (Direction == eDirection.CW) {
|
||
if (StartAngle < EndAngle) m_endAngle -= 360;
|
||
else if (EndAngle - StartAngle < -360) m_endAngle += 360;
|
||
else;
|
||
} else;
|
||
|
||
m_sweepAngle = EndAngle - StartAngle;
|
||
drawingNodeSet = false;
|
||
} else m_endAngle = SweepAngle + m_startAngle;
|
||
|
||
if (m_useHatching && !_isLoading) {
|
||
GenerateHatch();
|
||
}
|
||
}
|
||
}
|
||
|
||
[Browsable(false)]
|
||
[ReadOnly(false)]
|
||
[Category("Geometry")]
|
||
[DisplayName("End Angle")]
|
||
[Description("End Angle")]
|
||
[JsonIgnore]
|
||
public float EndAngle {
|
||
get { return m_endAngle; }
|
||
set {
|
||
if (Direction == eDirection.CCW) {
|
||
if (value < StartAngle) m_endAngle = 360 + value;
|
||
else m_endAngle = value;
|
||
} else if (Direction == eDirection.CW) {
|
||
if (value > StartAngle) m_endAngle = -360 + value;
|
||
else m_endAngle = value;
|
||
} else m_endAngle = value;
|
||
|
||
// Drawing <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Sweep Angle <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>ֵ<EFBFBD><D6B5><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
if (drawingNodeSet) {
|
||
m_sweepAngle = m_endAngle - m_startAngle;
|
||
}
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(true)]
|
||
[CustomSortedCategory("Geometry", 3, 6)]
|
||
[CustomSortedDisplayName("Start Point [X,Y](mm)", 1, 3)]
|
||
[Description("Start Point")]
|
||
[TypeConverter(typeof(PointFConverter))]
|
||
[XmlSerializable]
|
||
public PointF PF1 {
|
||
get {
|
||
return StartAnglePoint.Point;
|
||
}
|
||
set {
|
||
StartAnglePoint = new UnitPoint(value);
|
||
StartAngle = (float)HitUtil.RadiansToDegrees(HitUtil.AngleROncircle(m_center, new UnitPoint(value)));
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(true)]
|
||
[CustomSortedCategory("Geometry", 3, 6)]
|
||
[CustomSortedDisplayName("End Point [X,Y](mm)", 2, 3)]
|
||
[Description("End Point")]
|
||
[TypeConverter(typeof(PointFConverter))]
|
||
[XmlSerializable]
|
||
public PointF PF2 {
|
||
get {
|
||
return EndAnglePoint.Point;
|
||
}
|
||
set {
|
||
EndAnglePoint = new UnitPoint(value);
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
float m_angle;
|
||
[Browsable(false)]
|
||
[JsonIgnore]
|
||
public float Angle {
|
||
get {
|
||
return StartAngle - EndAngle;
|
||
}
|
||
set {
|
||
m_angle = (float)value;
|
||
}
|
||
}
|
||
|
||
public virtual IDrawObject Clone()
|
||
{
|
||
Arc a = new Arc();
|
||
a.Copy(this);
|
||
return a;
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Geometry", 3, 6)]
|
||
[CustomSortedDisplayName("Sweep Angle[deg]", 4, 8)]
|
||
[Description("unit : degree / Positive Number")]
|
||
[JsonIgnore]
|
||
public float AbsSweepAngle {
|
||
get {
|
||
m_absSweepAngle = Math.Abs(SweepAngle);
|
||
return m_absSweepAngle;
|
||
}
|
||
set {
|
||
// Sweep Angle<6C><65> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Է<EFBFBD><D4B7><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
if (value > 0) {
|
||
m_absSweepAngle = value;
|
||
if (Direction == eDirection.CCW) SweepAngle = m_absSweepAngle;
|
||
if (Direction == eDirection.CW) SweepAngle = -m_absSweepAngle;
|
||
}
|
||
}
|
||
}
|
||
|
||
[Browsable(false)]
|
||
[ReadOnly(true)]
|
||
[CustomSortedCategory("Geometry", 3, 6)]
|
||
[CustomSortedDisplayName("Sweep Angle[deg]", 4, 8)]
|
||
[Description("unit : degree")]
|
||
[XmlSerializable]
|
||
public float SweepAngle {
|
||
get {
|
||
return m_sweepAngle;
|
||
}
|
||
set {
|
||
m_sweepAngle = value;
|
||
m_length = m_radius * value * (float)Math.PI / 180;
|
||
|
||
bool ispositive = m_sweepAngle >= 0 ? true : false;
|
||
|
||
if (ispositive && Direction == eDirection.CCW) {
|
||
if (m_sweepAngle <= 3600) m_endAngle = StartAngle + m_sweepAngle;
|
||
else m_endAngle = StartAngle + 3600;
|
||
}
|
||
if (!ispositive && Direction == eDirection.CW) {
|
||
if (-3600 <= m_sweepAngle) m_endAngle = StartAngle + m_sweepAngle;
|
||
else m_endAngle = StartAngle - 3600;
|
||
}
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[CustomSortedCategory("Geometry", 3, 6)]
|
||
[CustomSortedDisplayName("Length[mm]", 5, 8)]
|
||
[Description("unit : mm / Positive Number")]
|
||
[JsonIgnore]
|
||
public float Length {
|
||
get {
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD>̱<EFBFBD> <20><><EFBFBD><EFBFBD>, <20>Ҽ<EFBFBD> 5<><35>° <20>ڸ<EFBFBD><DAB8><EFBFBD><EFBFBD><EFBFBD> <20>ݿø<DDBF>.
|
||
m_length = (float)Math.Round(Math.Abs(SweepAngle) * (Radius * (float)Math.PI / 180), 5);
|
||
return m_length;
|
||
}
|
||
set {
|
||
if (value > 0) {
|
||
m_length = Math.Abs(value);
|
||
|
||
if (Direction == eDirection.CCW) SweepAngle = m_length / (Radius * (float)Math.PI / 180);
|
||
|
||
if (Direction == eDirection.CW) SweepAngle = -m_length / (Radius * (float)Math.PI / 180);
|
||
}
|
||
}
|
||
}
|
||
|
||
public RectangleF GetBoundingRect(ICanvas canvas)
|
||
{
|
||
float thWidth = Line.ThresholdWidth(canvas, Width, ThresholdPixel);
|
||
if (thWidth < Width)
|
||
thWidth = Width;
|
||
float r = m_radius + thWidth / 2;
|
||
RectangleF rect = HitUtil.CircleBoundingRect(m_center, r);
|
||
// if drawing either angle then include the mouse point in the ractangle - this is to redraw (erase) the line drawn
|
||
// from center point to mouse point
|
||
if (m_curPoint == eCurrentPoint.startAngle || m_curPoint == eCurrentPoint.endAngle)
|
||
rect = RectangleF.Union(rect, new RectangleF(m_lastPoint.Point, new SizeF(0, 0)));
|
||
return rect;
|
||
}
|
||
|
||
public virtual void Draw(ICanvas canvas, RectangleF unitrect)
|
||
{
|
||
Action drawHatch = () => {
|
||
if (m_useHatching) {
|
||
foreach (var obj in _hatchObjects) {
|
||
// HatchOnly <20><><EFBFBD><EFBFBD> <20><> <20><>, <20><><EFBFBD>ο<EFBFBD> <20><EFBFBD><D7B8><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
if (m_hatchMarkType == eHatchMarkType.Hatch_Only) {
|
||
if (obj is Arc arcObj && arcObj.InnerArcFlag == FLAG_INNER_ARC) {
|
||
continue;
|
||
}
|
||
}
|
||
|
||
obj.Draw(canvas, unitrect);
|
||
}
|
||
}
|
||
};
|
||
|
||
Action drawOutline = () => {
|
||
Color color = WeldingParameterIDEditor.weldingColorList[(int)WeldingParameterID - 1];
|
||
Pen pen = canvas.CreatePen(color, Width);
|
||
canvas.DrawArc(canvas, pen, m_center, m_radius, StartAngle, SweepAngle);
|
||
if (m_direction == eDirection.CCW) {
|
||
DrawUtils.DrawArrowNode(canvas, EndAnglePoint, EndAngle + 90, pen);
|
||
}
|
||
else {
|
||
DrawUtils.DrawArrowNode(canvas, EndAnglePoint, EndAngle - 90, pen);
|
||
}
|
||
};
|
||
|
||
if (!m_useHatching) {
|
||
drawOutline();
|
||
}
|
||
|
||
switch (m_hatchMarkType) {
|
||
case eHatchMarkType.Outline_and_Hatch:
|
||
drawOutline();
|
||
drawHatch();
|
||
break;
|
||
case eHatchMarkType.Hatch_and_Outline:
|
||
drawHatch();
|
||
drawOutline();
|
||
break;
|
||
case eHatchMarkType.Hatch_Only:
|
||
drawHatch();
|
||
break;
|
||
}
|
||
|
||
if (Selected) {
|
||
canvas.DrawArc(canvas, DrawUtils.SelectedPen, m_center, m_radius, StartAngle, SweepAngle);
|
||
DrawUtils.DrawNode(canvas, m_center);
|
||
DrawNodes(canvas);
|
||
}
|
||
}
|
||
private void GenerateHatch()
|
||
{
|
||
_hatchObjects.Clear();
|
||
if (!m_useHatching) {
|
||
return;
|
||
}
|
||
|
||
if (HatchInnerRadius > 0 && HatchInnerRadius < Radius) {
|
||
Arc innerArc = new Arc(this.m_arcType);
|
||
innerArc.Center = this.Center;
|
||
innerArc.Radius = this.HatchInnerRadius;
|
||
innerArc.StartAngle = this.StartAngle;
|
||
innerArc.EndAngle = this.EndAngle;
|
||
innerArc.SweepAngle = this.SweepAngle;
|
||
innerArc.Direction = this.Direction;
|
||
innerArc.Color = this.Color;
|
||
innerArc.Width = this.Width;
|
||
innerArc.UseLayerColor = false;
|
||
innerArc.UseLayerWidth = false;
|
||
innerArc.InnerArcFlag = FLAG_INNER_ARC;
|
||
innerArc.ScannerParamNo = this.ScannerParamNo;
|
||
innerArc.WeldingParameterID = this.WeldingParameterID;
|
||
innerArc.Enabled = this.Enabled;
|
||
_hatchObjects.Add(innerArc);
|
||
}
|
||
|
||
if (m_hatchFillingType == eHatchFillingType.Filling_Lines) {
|
||
GenerateLineHatch();
|
||
}
|
||
else {
|
||
GenerateArcHatch();
|
||
}
|
||
}
|
||
|
||
//private void GenerateLineHatch()
|
||
//{
|
||
// float outerR = Radius - HatchMarjin;
|
||
// float innerR = (HatchInnerRadius > 0) ? HatchInnerRadius + HatchMarjin : 0;
|
||
// if (outerR <= innerR) {
|
||
// return;
|
||
// }
|
||
|
||
// float top = (float)(Center.Y + outerR);
|
||
// float bottom = (float)(Center.Y - outerR);
|
||
// float interval = (m_hatchInterval < 0.01f) ? 0.01f : m_hatchInterval;
|
||
// bool isLeftToRight = true;
|
||
|
||
// for (float currentY = top; currentY >= bottom; currentY -= interval) {
|
||
// List<float> validXs = new List<float>();
|
||
// validXs.AddRange(GetCircleIntersections(outerR, currentY));
|
||
// if (innerR > 0) {
|
||
// validXs.AddRange(GetCircleIntersections(innerR, currentY));
|
||
// }
|
||
// validXs.Sort();
|
||
|
||
// for (int i = 0; i < validXs.Count - 1; i += 2) {
|
||
// float x1 = validXs[i];
|
||
// float x2 = validXs[i + 1];
|
||
// if (Math.Abs(x1 - x2) < 0.001) continue;
|
||
// UnitPoint p1 = new UnitPoint(x1, currentY);
|
||
// UnitPoint p2 = new UnitPoint(x2, currentY);
|
||
// Line hatchLine;
|
||
// if (isLeftToRight) {
|
||
// hatchLine = new Line(p1, p2, 0.01f, Color.Yellow);
|
||
// }
|
||
// else {
|
||
// hatchLine = new Line(p2, p1, 0.01f, Color.Yellow);
|
||
// }
|
||
// hatchLine.UseLayerColor = false;
|
||
// hatchLine.UseLayerWidth = false;
|
||
// _hatchObjects.Add(hatchLine);
|
||
// }
|
||
// isLeftToRight = !isLeftToRight;
|
||
// }
|
||
//}
|
||
private void GenerateLineHatch()
|
||
{
|
||
float outerR = Radius - HatchMarjin;
|
||
float innerR = (HatchInnerRadius > 0) ? HatchInnerRadius + HatchMarjin : 0;
|
||
|
||
if (outerR <= innerR) {
|
||
return;
|
||
}
|
||
|
||
float top = (float)(Center.Y + outerR);
|
||
float bottom = (float)(Center.Y - outerR);
|
||
float interval = (m_hatchInterval < 0.01f) ? 0.01f : m_hatchInterval;
|
||
bool isZigZagToggle = true;
|
||
|
||
for (float currentY = top; currentY >= bottom; currentY -= interval) {
|
||
List<float> validXs = new List<float>();
|
||
|
||
validXs.AddRange(GetCircleIntersections(outerR, currentY));
|
||
if (innerR > 0) {
|
||
validXs.AddRange(GetCircleIntersections(innerR, currentY));
|
||
}
|
||
validXs.Sort();
|
||
|
||
for (int i = 0; i < validXs.Count - 1; i += 2) {
|
||
float x1 = validXs[i];
|
||
float x2 = validXs[i + 1];
|
||
|
||
if (Math.Abs(x1 - x2) < 0.001) {
|
||
continue;
|
||
}
|
||
|
||
UnitPoint p1 = new UnitPoint(x1, currentY);
|
||
UnitPoint p2 = new UnitPoint(x2, currentY);
|
||
|
||
bool currentDirIsLeft = true;
|
||
|
||
switch (m_hatchLineDir) {
|
||
case eHatchLineDir.ZigZag:
|
||
currentDirIsLeft = isZigZagToggle;
|
||
break;
|
||
case eHatchLineDir.LeftToRight:
|
||
currentDirIsLeft = true;
|
||
break;
|
||
case eHatchLineDir.RightToLeft:
|
||
currentDirIsLeft = false;
|
||
break;
|
||
}
|
||
|
||
Line hatchLine;
|
||
if (currentDirIsLeft) {
|
||
hatchLine = new Line(p1, p2, 0.01f, Color.Yellow);
|
||
}
|
||
else {
|
||
hatchLine = new Line(p2, p1, 0.01f, Color.Yellow);
|
||
}
|
||
|
||
hatchLine.UseLayerColor = false;
|
||
hatchLine.UseLayerWidth = false;
|
||
|
||
hatchLine.ScannerParamNo = this.ScannerParamNo;
|
||
hatchLine.WeldingParameterID = this.WeldingParameterID;
|
||
hatchLine.Enabled = this.Enabled;
|
||
|
||
_hatchObjects.Add(hatchLine);
|
||
}
|
||
|
||
isZigZagToggle = !isZigZagToggle;
|
||
}
|
||
}
|
||
private List<float> GetCircleIntersections(float r, float y)
|
||
{
|
||
List<float> xs = new List<float>();
|
||
double dy = y - Center.Y;
|
||
if (Math.Abs(dy) > r) {
|
||
return xs;
|
||
}
|
||
double term = r * r - dy * dy;
|
||
if (term < 0) {
|
||
term = 0;
|
||
}
|
||
double dx = Math.Sqrt(term);
|
||
float[] candidates = new float[] { (float)(Center.X - dx), (float)(Center.X + dx) };
|
||
foreach (float x in candidates) {
|
||
if (IsAngleInArc(x, y)) {
|
||
xs.Add(x);
|
||
}
|
||
}
|
||
return xs;
|
||
}
|
||
|
||
private void GenerateArcHatch()
|
||
{
|
||
float outerR = Radius - HatchMarjin;
|
||
float innerR = (HatchInnerRadius > 0) ? HatchInnerRadius + HatchMarjin : 0;
|
||
float interval = (m_hatchInterval < 0.01f) ? 0.01f : m_hatchInterval;
|
||
if (outerR <= innerR) {
|
||
return;
|
||
}
|
||
bool cw = (Direction == eDirection.CW);
|
||
|
||
// Inner Radius <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ο<EFBFBD><CEBF><EFBFBD> <20>ܺη<DCBA> (Inside -> Outside)
|
||
if (HatchInnerRadius > 0) {
|
||
for (float r = innerR; r <= outerR; r += interval) {
|
||
CreateHatchArc(r, ref cw);
|
||
}
|
||
}
|
||
// Inner Radius <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ܺο<DCBA><CEBF><EFBFBD> <20><><EFBFBD>η<EFBFBD> (Outside -> Inside)
|
||
else {
|
||
for (float r = outerR; r >= innerR; r -= interval) {
|
||
CreateHatchArc(r, ref cw);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void CreateHatchArc(float r, ref bool cw)
|
||
{
|
||
Arc hatchArc = new Arc(eArcType.typeCenterRadius);
|
||
hatchArc.Center = this.Center;
|
||
hatchArc.Radius = r;
|
||
hatchArc.StartAngle = this.StartAngle;
|
||
hatchArc.EndAngle = this.EndAngle;
|
||
|
||
hatchArc.Direction = cw ? eDirection.CW : eDirection.CCW;
|
||
cw = !cw; // <20><><EFBFBD><EFBFBD> <20><>ũ<EFBFBD><C5A9> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
|
||
hatchArc.Color = Color.Yellow;
|
||
hatchArc.UseLayerColor = false;
|
||
hatchArc.UseLayerWidth = false;
|
||
hatchArc.Width = 0.01f;
|
||
hatchArc.SweepAngle = this.SweepAngle;
|
||
|
||
hatchArc.ScannerParamNo = this.ScannerParamNo;
|
||
hatchArc.WeldingParameterID = this.WeldingParameterID;
|
||
hatchArc.Enabled = this.Enabled;
|
||
|
||
_hatchObjects.Add(hatchArc);
|
||
}
|
||
private bool IsAngleInArc(float x, float y)
|
||
{
|
||
if (this is Circle || Math.Abs(SweepAngle) >= 360) {
|
||
return true;
|
||
}
|
||
double angleRad = Math.Atan2(y - Center.Y, x - Center.X);
|
||
float angleDeg = (float)(angleRad * 180.0 / Math.PI);
|
||
if (angleDeg < 0) {
|
||
angleDeg += 360;
|
||
}
|
||
angleDeg %= 360;
|
||
float start = StartAngle % 360; if (start < 0) start += 360;
|
||
float end = EndAngle % 360; if (end < 0) end += 360;
|
||
bool isCCW = (Direction == eDirection.CCW);
|
||
if (!isCCW) {
|
||
float temp = start;
|
||
start = end;
|
||
end = temp;
|
||
}
|
||
float tolerance = 0.1f;
|
||
if (start <= end) {
|
||
return angleDeg >= start - tolerance && angleDeg <= end + tolerance;
|
||
}
|
||
else {
|
||
return angleDeg >= start - tolerance || angleDeg <= end + tolerance;
|
||
}
|
||
}
|
||
|
||
public bool drawingNodeSet = false;
|
||
public virtual void OnMouseMove(ICanvas canvas, UnitPoint point)
|
||
{
|
||
// ó<><C3B3> drawing <20><> <20><>, (<28>Ϸ<EFBFBD><CFB7>Ǹ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.)
|
||
drawingNodeSet = true;
|
||
|
||
m_lastPoint = point;
|
||
if (m_curPoint == eCurrentPoint.p1) {
|
||
m_point = point;
|
||
return;
|
||
}
|
||
if (m_curPoint == eCurrentPoint.p2) {
|
||
StartAngle = 0;
|
||
EndAngle = 360;
|
||
m_center = HitUtil.LineMidpoint(m_point, point);
|
||
m_radius = (float)HitUtil.Distance(m_center, point);
|
||
return;
|
||
}
|
||
if (m_curPoint == eCurrentPoint.center) {
|
||
m_center = point;
|
||
}
|
||
if (m_curPoint == eCurrentPoint.radius) {
|
||
//StartAngle = 0;
|
||
//EndAngle = 360;
|
||
m_radius = (float)HitUtil.Distance(m_center, point);
|
||
}
|
||
|
||
double angleToRound = 0;
|
||
if (System.Windows.Forms.Control.ModifierKeys == Keys.Control)
|
||
angleToRound = HitUtil.DegressToRadians(45);
|
||
|
||
if (m_curPoint == eCurrentPoint.startAngle) {
|
||
StartAngle = (float)HitUtil.RadiansToDegrees(HitUtil.LineAngleR(m_center, point, angleToRound));
|
||
}
|
||
if (m_curPoint == eCurrentPoint.endAngle) {
|
||
EndAngle = (float)HitUtil.RadiansToDegrees(HitUtil.LineAngleR(m_center, point, angleToRound));
|
||
}
|
||
}
|
||
|
||
public virtual eDrawObjectMouseDown OnMouseDown(ICanvas canvas, UnitPoint point, ISnapPoint snappoint)
|
||
{
|
||
OnMouseMove(canvas, point);
|
||
if (m_arcType == eArcType.type2point) {
|
||
if (m_curPoint == eCurrentPoint.p1) {
|
||
m_curPoint = eCurrentPoint.p2;
|
||
return eDrawObjectMouseDown.Continue;
|
||
}
|
||
if (m_curPoint == eCurrentPoint.p2) {
|
||
m_curPoint = eCurrentPoint.startAngle;
|
||
return eDrawObjectMouseDown.Continue;
|
||
}
|
||
if (m_curPoint == eCurrentPoint.startAngle) {
|
||
m_curPoint = eCurrentPoint.endAngle;
|
||
return eDrawObjectMouseDown.Continue;
|
||
}
|
||
if (m_curPoint == eCurrentPoint.endAngle) {
|
||
m_curPoint = eCurrentPoint.done;
|
||
OnMouseMove(canvas, point);
|
||
// <20>Ϸ<EFBFBD><CFB7>Ǹ<EFBFBD>, drawingNode<64><65> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||
drawingNodeSet = false;
|
||
Selected = false;
|
||
return eDrawObjectMouseDown.Done;
|
||
}
|
||
}
|
||
if (m_arcType == eArcType.typeCenterRadius) {
|
||
if (m_curPoint == eCurrentPoint.center) {
|
||
m_curPoint = eCurrentPoint.radius;
|
||
return eDrawObjectMouseDown.Continue;
|
||
}
|
||
if (m_curPoint == eCurrentPoint.radius) {
|
||
m_curPoint = eCurrentPoint.startAngle;
|
||
return eDrawObjectMouseDown.Continue;
|
||
}
|
||
if (m_curPoint == eCurrentPoint.startAngle) {
|
||
m_curPoint = eCurrentPoint.endAngle;
|
||
return eDrawObjectMouseDown.Continue;
|
||
}
|
||
if (m_curPoint == eCurrentPoint.endAngle) {
|
||
m_curPoint = eCurrentPoint.done;
|
||
OnMouseMove(canvas, point);
|
||
Selected = false;
|
||
// <20>Ϸ<EFBFBD><CFB7>Ǹ<EFBFBD>, drawingNode<64><65> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||
drawingNodeSet = false;
|
||
return eDrawObjectMouseDown.Done;
|
||
}
|
||
}
|
||
return eDrawObjectMouseDown.Done;
|
||
}
|
||
|
||
public virtual void OnMouseUp(ICanvas canvas, UnitPoint point, ISnapPoint snappoint)
|
||
{
|
||
}
|
||
|
||
public virtual void OnKeyDown(ICanvas canvas, KeyEventArgs e)
|
||
{
|
||
if (e.KeyCode == Keys.D && (m_curPoint == eCurrentPoint.startAngle || m_curPoint == eCurrentPoint.endAngle)) {
|
||
if (Direction == eDirection.CW)
|
||
Direction = eDirection.CCW;
|
||
else
|
||
Direction = eDirection.CW;
|
||
e.Handled = true;
|
||
}
|
||
if (e.KeyCode == Keys.C) // switch to centerRadius mode
|
||
{/*
|
||
m_center = UnitPoint.Empty;
|
||
m_radius = 0;
|
||
m_startAngle = 0;
|
||
m_endAngle = 0;
|
||
m_arcType = eArcType.typeCenterRadius;
|
||
m_curPoint = eCurrentPoint.center;
|
||
e.Handled = true;
|
||
canvas.Invalidate(false);*/
|
||
}
|
||
if (e.KeyCode == Keys.D2) // switch to 2 pointmode
|
||
{
|
||
m_center = UnitPoint.Empty;
|
||
m_radius = 0;
|
||
m_startAngle = 0;
|
||
m_endAngle = 0;
|
||
m_arcType = eArcType.type2point;
|
||
m_curPoint = eCurrentPoint.p1;
|
||
e.Handled = true;
|
||
canvas.Invalidate(false);
|
||
}
|
||
}
|
||
|
||
public virtual bool PointInObject(ICanvas canvas, UnitPoint point)
|
||
{
|
||
RectangleF boundingrect = GetBoundingRect(canvas);
|
||
if (boundingrect.Contains(point.Point) == false)
|
||
return false;
|
||
float thWidth = Line.ThresholdWidth(canvas, Width, ThresholdPixel);
|
||
if (HitUtil.PointInPoint(m_center, point, thWidth))
|
||
return true;
|
||
return HitUtil.IsPointInArc(m_center, m_radius, point, thWidth / 2, ClientRect);
|
||
}
|
||
|
||
public virtual bool ObjectInRectangle(ICanvas canvas, RectangleF rect, bool anyPoint)
|
||
{
|
||
float r = m_radius + Width / 2;
|
||
//RectangleF boundingrect = HitUtil.CircleBoundingRect(m_center, r);
|
||
RectangleF boundingrect = ClientRect;
|
||
if (anyPoint) {
|
||
UnitPoint lp1 = new UnitPoint(rect.Left, rect.Top);
|
||
UnitPoint lp2 = new UnitPoint(rect.Left, rect.Bottom);
|
||
if (HitUtil.CircleIntersectWithLine(m_center, m_radius, lp1, lp2))
|
||
return true;
|
||
lp1 = new UnitPoint(rect.Left, rect.Bottom);
|
||
lp2 = new UnitPoint(rect.Right, rect.Bottom);
|
||
if (HitUtil.CircleIntersectWithLine(m_center, m_radius, lp1, lp2))
|
||
return true;
|
||
lp1 = new UnitPoint(rect.Left, rect.Top);
|
||
lp2 = new UnitPoint(rect.Right, rect.Top);
|
||
if (HitUtil.CircleIntersectWithLine(m_center, m_radius, lp1, lp2))
|
||
return true;
|
||
lp1 = new UnitPoint(rect.Left, rect.Top);
|
||
lp2 = new UnitPoint(rect.Right, rect.Top);
|
||
if (HitUtil.CircleIntersectWithLine(m_center, m_radius, lp1, lp2))
|
||
return true;
|
||
|
||
lp1 = new UnitPoint(rect.Right, rect.Top);
|
||
lp2 = new UnitPoint(rect.Right, rect.Bottom);
|
||
if (HitUtil.CircleIntersectWithLine(m_center, m_radius, lp1, lp2))
|
||
return true;
|
||
}
|
||
return rect.Contains(boundingrect);
|
||
}
|
||
|
||
[Browsable(false)]
|
||
[ReadOnly(false)]
|
||
public virtual UnitPoint RepeatStartingPoint {
|
||
get { return UnitPoint.Empty; }
|
||
}
|
||
|
||
public virtual INodePoint NodePoint(ICanvas canvas, UnitPoint point)
|
||
{
|
||
float thWidth = Line.ThresholdWidth(canvas, Width, ThresholdPixel);
|
||
if (HitUtil.PointInPoint(m_center, point, thWidth))
|
||
return new NodePointArcCenter(this);
|
||
if (HitUtil.PointInPoint(StartAnglePoint, point, thWidth)) {
|
||
m_curPoint = eCurrentPoint.startAngle;
|
||
m_lastPoint = m_center;
|
||
return new NodePointArcAngle(this);
|
||
}
|
||
if (HitUtil.PointInPoint(EndAnglePoint, point, thWidth)) {
|
||
m_curPoint = eCurrentPoint.endAngle;
|
||
m_lastPoint = m_center;
|
||
return new NodePointArcAngle(this);
|
||
}
|
||
if (HitUtil.PointInPoint(RadiusPoint, point, thWidth)) {
|
||
m_curPoint = eCurrentPoint.radius;
|
||
m_lastPoint = m_center;
|
||
return new NodePointArcRadius(this);
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public virtual ISnapPoint SnapPoint(ICanvas canvas, UnitPoint point, List<IDrawObject> otherobj, Type[] runningsnaptypes, Type usersnaptype)
|
||
{
|
||
float thWidth = Line.ThresholdWidth(canvas, Width, ThresholdPixel);
|
||
if (runningsnaptypes != null) {
|
||
foreach (Type snaptype in runningsnaptypes) {
|
||
if (snaptype == typeof(QuadrantSnapPoint)) {
|
||
UnitPoint p = HitUtil.NearestPointOnCircle(m_center, m_radius, point, 90);
|
||
if (p != UnitPoint.Empty && HitUtil.PointInPoint(p, point, thWidth))
|
||
return new QuadrantSnapPoint(canvas, this, p);
|
||
}
|
||
if (snaptype == typeof(DivisionSnapPoint)) {
|
||
double angle = 360 / Divisions;
|
||
UnitPoint p = HitUtil.NearestPointOnCircle(m_center, m_radius, point, angle);
|
||
if (p != UnitPoint.Empty && HitUtil.PointInPoint(p, point, thWidth))
|
||
return new DivisionSnapPoint(canvas, this, p);
|
||
}
|
||
if (snaptype == typeof(CenterSnapPoint)) {
|
||
if (HitUtil.PointInPoint(m_center, point, thWidth))
|
||
return new CenterSnapPoint(canvas, this, m_center);
|
||
}
|
||
if (snaptype == typeof(VertextSnapPoint)) {
|
||
if (HitUtil.PointInPoint(StartAnglePoint, point, thWidth))
|
||
return new VertextSnapPoint(canvas, this, StartAnglePoint);
|
||
if (HitUtil.PointInPoint(EndAnglePoint, point, thWidth))
|
||
return new VertextSnapPoint(canvas, this, EndAnglePoint);
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
if (usersnaptype == typeof(NearestSnapPoint)) {
|
||
UnitPoint p = HitUtil.NearestPointOnCircle(m_center, m_radius, point, 0);
|
||
if (p != UnitPoint.Empty)
|
||
return new NearestSnapPoint(canvas, this, p);
|
||
}
|
||
if (usersnaptype == typeof(PerpendicularSnapPoint)) {
|
||
UnitPoint p = HitUtil.NearestPointOnCircle(m_center, m_radius, point, 0);
|
||
if (p != UnitPoint.Empty)
|
||
return new PerpendicularSnapPoint(canvas, this, p);
|
||
}
|
||
if (usersnaptype == typeof(QuadrantSnapPoint)) {
|
||
UnitPoint p = HitUtil.NearestPointOnCircle(m_center, m_radius, point, 90);
|
||
if (p != UnitPoint.Empty)
|
||
return new QuadrantSnapPoint(canvas, this, p);
|
||
}
|
||
if (usersnaptype == typeof(DivisionSnapPoint)) {
|
||
double angle = 360 / Divisions;
|
||
UnitPoint p = HitUtil.NearestPointOnCircle(m_center, m_radius, point, angle);
|
||
if (p != UnitPoint.Empty)
|
||
return new DivisionSnapPoint(canvas, this, p);
|
||
}
|
||
if (usersnaptype == typeof(TangentSnapPoint)) {
|
||
IDrawObject drawingObject = canvas.CurrentObject;
|
||
UnitPoint p = UnitPoint.Empty;
|
||
if (drawingObject is LineEdit) {
|
||
UnitPoint mousepoint = point;
|
||
point = ((LineEdit)drawingObject).P1;
|
||
UnitPoint p1 = HitUtil.TangentPointOnCircle(m_center, m_radius, point, false);
|
||
UnitPoint p2 = HitUtil.TangentPointOnCircle(m_center, m_radius, point, true);
|
||
double d1 = HitUtil.Distance(mousepoint, p1);
|
||
double d2 = HitUtil.Distance(mousepoint, p2);
|
||
if (d1 <= d2)
|
||
return new TangentSnapPoint(canvas, this, p1);
|
||
else
|
||
return new TangentSnapPoint(canvas, this, p2);
|
||
}
|
||
//if (p != PointF.Empty)
|
||
return new TangentSnapPoint(canvas, this, p);
|
||
}
|
||
if (usersnaptype == typeof(CenterSnapPoint)) {
|
||
return new CenterSnapPoint(canvas, this, m_center);
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public virtual void Move(UnitPoint offset)
|
||
{
|
||
m_center.X += offset.X;
|
||
m_center.Y += offset.Y;
|
||
m_lastPoint = m_center;
|
||
|
||
if (m_useHatching) {
|
||
GenerateHatch();
|
||
}
|
||
}
|
||
|
||
public void Rotate(float angle, UnitPoint center)
|
||
{
|
||
double angleFromCenterToStart = 0, angleFromCenterToEnd = 0, angleFromOriginToCenter = 0;
|
||
|
||
UnitPoint m_pf1 = new UnitPoint();
|
||
UnitPoint m_pf2 = new UnitPoint();
|
||
|
||
// 1. Center Line<6E><65><EFBFBD><EFBFBD> StartPoint<6E><74> EndPoint <20><><EFBFBD><EFBFBD>.
|
||
UnitPoint v1 = Center - center;
|
||
UnitPoint v2 = new UnitPoint(PF1.X - Center.X, PF1.Y - Center.Y);
|
||
UnitPoint v3 = new UnitPoint(PF2.X - Center.X, PF2.Y - Center.Y);
|
||
|
||
// 2. <20>߽<EFBFBD> ȸ<><C8B8><EFBFBD><EFBFBD>Ŵ.
|
||
Center = HitUtil.RotatePoint(angle, Center, center);
|
||
|
||
// 3. <20>߽<EFBFBD> ȸ<><C8B8> <20><>, <20>߽<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> point <20><><EFBFBD><EFBFBD>.
|
||
angleFromOriginToCenter = Math.Atan2(Center.Y - center.Y, Center.X - center.X) - Math.PI / 2;// + Math.PI/2;
|
||
if (angleFromOriginToCenter > Math.PI) {
|
||
angleFromOriginToCenter -= 2 * Math.PI;
|
||
} else if (angleFromOriginToCenter <= -Math.PI) {
|
||
angleFromOriginToCenter += 2 * Math.PI;
|
||
}
|
||
//else;
|
||
|
||
if (angleFromOriginToCenter != -Math.PI / 2) {
|
||
angleFromCenterToStart = Math.Atan2(v2.Y, v2.X) - Math.Atan2(v1.Y, v1.X);
|
||
angleFromCenterToEnd = Math.Atan2(v3.Y, v3.X) - Math.Atan2(v1.Y, v1.X);
|
||
|
||
if (angleFromCenterToStart > Math.PI) { angleFromCenterToStart -= 2 * Math.PI; } else if (angleFromCenterToStart <= -Math.PI) { angleFromCenterToStart += 2 * Math.PI; }
|
||
//else;
|
||
|
||
if (angleFromCenterToEnd > Math.PI) { angleFromCenterToEnd -= 2 * Math.PI; } else if (angleFromCenterToEnd <= -Math.PI) { angleFromCenterToEnd += 2 * Math.PI; }
|
||
//else;
|
||
|
||
m_pf1 = PointToAngles(Center, Radius, angleFromOriginToCenter, angleFromCenterToStart);
|
||
m_pf2 = PointToAngles(Center, Radius, angleFromOriginToCenter, angleFromCenterToEnd);
|
||
} else {
|
||
m_pf1 = HitUtil.RotatePoint(angle, StartAnglePoint, center);
|
||
m_pf2 = HitUtil.RotatePoint(angle, EndAnglePoint, center);
|
||
}
|
||
|
||
PF1 = new PointF((float)m_pf1.X, (float)m_pf1.Y);
|
||
PF2 = new PointF((float)m_pf2.X, (float)m_pf2.Y);
|
||
|
||
if (m_useHatching) {
|
||
GenerateHatch();
|
||
}
|
||
}
|
||
|
||
public UnitPoint PointToAngles(UnitPoint center, double length, double angle0, double angle1)
|
||
{
|
||
UnitPoint p1 = new UnitPoint();
|
||
p1.X = center.X - length * Math.Cos(angle0) * Math.Sin(angle1) - length * Math.Sin(angle0) * Math.Cos(angle1);
|
||
p1.Y = center.Y - length * Math.Sin(angle0) * Math.Sin(angle1) + length * Math.Cos(angle0) * Math.Cos(angle1);
|
||
return p1;
|
||
}
|
||
|
||
public void MakeLength(float distance)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual string GetInfoAsString()
|
||
{
|
||
return string.Format("{1:D3} {0}@{2}, r={3:f4}, A1={4:f4}, A2={5:f4}",
|
||
this.Type,
|
||
No + 1,
|
||
Center.PosAsString(),
|
||
Radius,
|
||
StartAngle,
|
||
EndAngle);
|
||
}
|
||
#endregion
|
||
|
||
#region ISerialize
|
||
public virtual 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
|
||
|
||
protected static int ThresholdPixel = 6;
|
||
protected static int Divisions = 8;
|
||
public enum eCurrentPoint
|
||
{
|
||
p1,
|
||
p2,
|
||
center,
|
||
radius,
|
||
startAngle,
|
||
endAngle,
|
||
done,
|
||
}
|
||
|
||
[Browsable(false)]
|
||
[ReadOnly(false)]
|
||
public eCurrentPoint CurrentPoint {
|
||
get { return m_curPoint; }
|
||
set { m_curPoint = value; }
|
||
}
|
||
|
||
public enum eArcType
|
||
{
|
||
typeCenterRadius,
|
||
type2point,
|
||
}
|
||
|
||
protected virtual void DrawNodes(ICanvas canvas)
|
||
{
|
||
if (m_curPoint == eCurrentPoint.startAngle && m_lastPoint != UnitPoint.Empty)
|
||
canvas.DrawLine(canvas, DrawUtils.SelectedPen, m_center, m_lastPoint);
|
||
if (m_curPoint == eCurrentPoint.endAngle && m_lastPoint != UnitPoint.Empty)
|
||
canvas.DrawLine(canvas, DrawUtils.SelectedPen, m_center, m_lastPoint);
|
||
|
||
DrawUtils.DrawNode(canvas, StartAnglePoint);
|
||
DrawUtils.DrawNode(canvas, EndAnglePoint);
|
||
DrawUtils.DrawNode(canvas, RadiusPoint);
|
||
}
|
||
|
||
protected UnitPoint AnglePoint(float angle)
|
||
{
|
||
return HitUtil.PointOncircle(m_center, m_radius, HitUtil.DegressToRadians(angle));
|
||
}
|
||
|
||
protected UnitPoint RadiusPoint {
|
||
get {
|
||
float angle = StartAngle + SweepAngle / 2;
|
||
return AnglePoint(angle);
|
||
}
|
||
}
|
||
|
||
protected UnitPoint StartAnglePoint {
|
||
get { return AnglePoint(StartAngle); }
|
||
set {
|
||
// StartAnglePoint<6E><74> set<65>ϱ<EFBFBD> <20><> StartAngle<6C><65> <20>̹<EFBFBD> <20>ٲپ<D9B2><D9BE><EFBFBD>. PF1 <20><><EFBFBD><EFBFBD>.
|
||
//StartAngle = (float)HitUtil.RadiansToDegrees(HitUtil.AngleROncircle(m_center, value));
|
||
m_radius = (float)HitUtil.Distance(m_center, value);
|
||
}
|
||
}
|
||
|
||
protected UnitPoint EndAnglePoint {
|
||
get { return AnglePoint(EndAngle); }
|
||
set {
|
||
// EndAngle<6C><65> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||
//EndAngle = (float)HitUtil.RadiansToDegrees(HitUtil.AngleROncircle(m_center, value));
|
||
m_radius = (float)HitUtil.Distance(m_center, value);
|
||
}
|
||
}
|
||
|
||
protected eArcType m_arcType = eArcType.type2point;
|
||
protected eCurrentPoint m_curPoint = eCurrentPoint.p1;
|
||
protected UnitPoint m_lastPoint;
|
||
protected UnitPoint m_point;
|
||
}
|
||
|
||
public class Circle : Arc
|
||
{
|
||
public Circle()
|
||
: base()
|
||
{
|
||
}
|
||
|
||
public Circle(Arc.eArcType type) : base(type)
|
||
{
|
||
}
|
||
|
||
public new static string ObjectType {
|
||
get { return "Circle"; }
|
||
}
|
||
|
||
public new string Type {
|
||
get { return ObjectType; }
|
||
}
|
||
|
||
public override IDrawObject Clone()
|
||
{
|
||
Circle a = new Circle();
|
||
a.Copy(this);
|
||
return a;
|
||
}
|
||
|
||
public override eDrawObjectMouseDown OnMouseDown(ICanvas canvas, UnitPoint point, ISnapPoint snappoint)
|
||
{
|
||
OnMouseMove(canvas, point);
|
||
if (m_arcType == eArcType.type2point) {
|
||
if (m_curPoint == eCurrentPoint.p1) {
|
||
m_curPoint = eCurrentPoint.p2;
|
||
return eDrawObjectMouseDown.Continue;
|
||
}
|
||
if (m_curPoint == eCurrentPoint.p2) {
|
||
m_curPoint = eCurrentPoint.done;
|
||
OnMouseMove(canvas, point);
|
||
Selected = false;
|
||
return eDrawObjectMouseDown.Done;
|
||
}
|
||
}
|
||
if (m_arcType == eArcType.typeCenterRadius) {
|
||
if (m_curPoint == eCurrentPoint.center) {
|
||
m_curPoint = eCurrentPoint.radius;
|
||
return eDrawObjectMouseDown.Continue;
|
||
}
|
||
if (m_curPoint == eCurrentPoint.radius) {
|
||
m_curPoint = eCurrentPoint.done;
|
||
OnMouseMove(canvas, point);
|
||
Selected = false;
|
||
return eDrawObjectMouseDown.Done;
|
||
}
|
||
}
|
||
return eDrawObjectMouseDown.Done;
|
||
}
|
||
|
||
protected override void DrawNodes(ICanvas canvas)
|
||
{
|
||
DrawUtils.DrawNode(canvas, AnglePoint(0));
|
||
DrawUtils.DrawNode(canvas, AnglePoint(90));
|
||
DrawUtils.DrawNode(canvas, AnglePoint(180));
|
||
DrawUtils.DrawNode(canvas, AnglePoint(270));
|
||
}
|
||
|
||
public override INodePoint NodePoint(ICanvas canvas, UnitPoint point)
|
||
{
|
||
float thWidth = Line.ThresholdWidth(canvas, Width, ThresholdPixel);
|
||
if (HitUtil.PointInPoint(Center, point, thWidth))
|
||
return new NodePointArcCenter(this);
|
||
bool radiushit = HitUtil.PointInPoint(AnglePoint(0), point, thWidth);
|
||
if (radiushit == false)
|
||
radiushit = HitUtil.PointInPoint(AnglePoint(90), point, thWidth);
|
||
if (radiushit == false)
|
||
radiushit = HitUtil.PointInPoint(AnglePoint(180), point, thWidth);
|
||
if (radiushit == false)
|
||
radiushit = HitUtil.PointInPoint(AnglePoint(270), point, thWidth);
|
||
if (radiushit) {
|
||
m_curPoint = eCurrentPoint.radius;
|
||
m_lastPoint = Center;
|
||
return new NodePointArcRadius(this);
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public override string GetInfoAsString()
|
||
{
|
||
return string.Format("{1:D3} {0}@{2}, r={3:f4}",
|
||
this.Type,
|
||
No + 1,
|
||
Center.PosAsString(),
|
||
Radius);
|
||
}
|
||
}
|
||
}
|