2026-06-05 13:44:39 +09:00

1805 lines
62 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}
}