2026-03-30 17:09:29 +09:00

1130 lines
39 KiB
C#
Raw 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.Windows.Forms;
using System.Xml;
namespace CoreUnit.Control.UserControl.Canvas
{
class NodePointArc3PointPoint : INodePoint
{
protected Arc3Point m_owner;
protected Arc3Point m_clone;
protected UnitPoint[] m_originalPoints = new UnitPoint[3];
protected UnitPoint[] m_endPoints = new UnitPoint[3];
protected Arc3Point.eCurrentPoint m_curPoint;
public NodePointArc3PointPoint(Arc3Point owner, Arc3Point.eCurrentPoint curpoint)
{
m_owner = owner;
m_clone = m_owner.Clone() as Arc3Point;
m_owner.Selected = false;
m_clone.Selected = true;
m_originalPoints[0] = m_owner.P1;
m_originalPoints[1] = m_owner.P2;
m_originalPoints[2] = m_owner.P3;
m_curPoint = curpoint;
}
#region INodePoint Members
public IDrawObject GetClone()
{
return m_clone;
}
public IDrawObject GetOriginal()
{
return m_owner;
}
public virtual void SetPosition(UnitPoint pos)
{
SetPoint(m_clone, pos);
}
/*
UnitPoint GetPoint()
{
if (m_curPoint == Arc3Point.eCurrentPoint.p1)
return m_clone.P1;
if (m_curPoint == Arc3Point.eCurrentPoint.p2)
return m_clone.P2;
if (m_curPoint == Arc3Point.eCurrentPoint.p3)
return m_clone.P3;
if (m_curPoint == Arc3Point.eCurrentPoint.startangle)
return m_clone.P1;
if (m_curPoint == Arc3Point.eCurrentPoint.endangle)
return m_clone.P3;
if (m_curPoint == Arc3Point.eCurrentPoint.radius)
return m_clone.P2;
return UnitPoint.Empty;
}
* */
void SetPoint(Arc3Point arc, UnitPoint pos)
{
if (m_curPoint == Arc3Point.eCurrentPoint.p1)
arc.P1 = pos;
if (m_curPoint == Arc3Point.eCurrentPoint.p2)
arc.P2 = pos;
if (m_curPoint == Arc3Point.eCurrentPoint.p3)
arc.P3 = pos;
double angleToRound = 0;
if (System.Windows.Forms.Control.ModifierKeys == Keys.Control)
angleToRound = HitUtil.DegressToRadians(45);
double angleR = HitUtil.LineAngleR(arc.Center, pos, angleToRound);
if (m_curPoint == Arc3Point.eCurrentPoint.startangle)
arc.P1 = HitUtil.PointOncircle(arc.Center, arc.Radius, angleR);
if (m_curPoint == Arc3Point.eCurrentPoint.endangle)
arc.P3 = HitUtil.PointOncircle(arc.Center, arc.Radius, angleR);
if (m_curPoint == Arc3Point.eCurrentPoint.radius) {
double radius = HitUtil.Distance(arc.Center, pos);
arc.P1 = HitUtil.PointOncircle(arc.Center, radius, HitUtil.DegressToRadians(arc.StartAngle));
arc.P2 = pos;
arc.P3 = HitUtil.PointOncircle(arc.Center, radius, HitUtil.DegressToRadians(arc.EndAngle));
}
arc.UpdateArcFrom3Points();
if ((m_curPoint == Arc3Point.eCurrentPoint.startangle) || (m_curPoint == Arc3Point.eCurrentPoint.endangle))
arc.UpdateCenterNodeFromAngles();
}
public virtual void Finish()
{
m_endPoints[0] = m_clone.P1;
m_endPoints[1] = m_clone.P2;
m_endPoints[2] = m_clone.P3;
m_owner.Copy(m_clone);
m_owner.Selected = true;
m_clone = null;
}
public void Cancel()
{
m_owner.Selected = true;
}
public virtual void Undo()
{
m_owner.P1 = m_originalPoints[0];
m_owner.P2 = m_originalPoints[1];
m_owner.P3 = m_originalPoints[2];
m_owner.UpdateArcFrom3Points();
}
public virtual void Redo()
{
m_owner.P1 = m_endPoints[0];
m_owner.P2 = m_endPoints[1];
m_owner.P3 = m_endPoints[2];
m_owner.UpdateArcFrom3Points();
}
public void OnKeyDown(ICanvas canvas, KeyEventArgs e)
{
}
#endregion
}
public class Arc3Point : DrawObjectBase, IArc, IDrawObject, ISerialize
{
public enum eArcType
{
kArc3P132,
kArc3P123,
}
eArcType m_type = eArcType.kArc3P132;
public enum eDirection
{
CW,
CCW,
}
UnitPoint m_p1 = UnitPoint.Empty;
UnitPoint m_p2 = UnitPoint.Empty;
UnitPoint m_p3 = UnitPoint.Empty;
[Browsable(false)]
public UnitPoint P1 {
get { return m_p1; }
set { m_p1 = value; }
}
[Browsable(false)]
public UnitPoint P2 {
get { return m_p2; }
set { m_p2 = value; }
}
[Browsable(false)]
public UnitPoint P3 {
get { return m_p3; }
set { m_p3 = value; }
}
UnitPoint m_center;
float m_radius;
float m_startAngle = 0;
float m_endAngle = 0;
[Browsable(false)]
public UnitPoint Center {
get { return m_center; }
set {
UnitPoint origin = m_center;
m_center = value;
m_p1 = m_p1 + value - origin;
m_p2 = m_p2 + value - origin;
m_p3 = m_p3 + value - origin;
}
}
public Arc3Point()
{
}
public Arc3Point(eArcType type)
{
m_type = type;
m_curPoint = eCurrentPoint.p1;
}
public override void InitializeFromModel(UnitPoint point, DrawingLayer layer, ISnapPoint snap)
{
P1 = P3 = point;
Width = layer.Width;
Color = layer.Color;
Selected = true;
OnMouseDown(null, point, snap);
}
public void Copy(Arc3Point acopy)
{
base.Copy(acopy);
m_p1 = acopy.m_p1;
m_p2 = acopy.m_p2;
m_p3 = acopy.m_p3;
m_center = acopy.m_center;
m_radius = acopy.m_radius;
m_startAngle = acopy.m_startAngle;
m_endAngle = acopy.m_endAngle;
m_direction = acopy.m_direction;
m_curPoint = acopy.m_curPoint;
m_RCCArc = acopy.m_RCCArc;
}
double GetSweep(double start, double end, eDirection direction)
{
double sweep = 360;
if (start == end)
return sweep;
if (direction == eDirection.CCW) {
if (end >= start)
sweep = end - start;
else
sweep = 360 - (start - end);
}
if (direction == eDirection.CW) {
if (end >= start)
sweep = -(360 - (end - start));
else
sweep = -(start - end);
}
return sweep;
}
[Browsable(true)]
[ReadOnly(false)]
[CustomSortedCategory("Geometry", 3, 6)]
[CustomSortedDisplayName("Sweep Angle[deg]", 4, 7)]
[Description("unit : degree")]
public float SweepAngle {
get { return (float)GetSweep(StartAngle, EndAngle, Direction); }
set {
float sweep = value;
bool isPositive = sweep >= 0 ? true : false;
if (isPositive && Direction == eDirection.CCW) {
if (sweep <= 2160) EndAngle = StartAngle + sweep;
else EndAngle = StartAngle + 2160;
}
if (!isPositive && Direction == eDirection.CW) {
if (-2160 <= sweep) EndAngle = StartAngle + sweep;
else EndAngle = StartAngle - 2160;
}
}
}
#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("Left,Bottom,Right,Top", 1, 1)]
[Description("Boundary of Object")]
[TypeConverter(typeof(RectangleFConverter))]
public RectangleF ClientRect {
get {
//lock (this) { return ScreenUtils.GetRect(Center, Radius, 0); }
List<UnitPoint> RectanglePoint = new List<UnitPoint>();
RectanglePoint.Add(P1);
if (m_type == eArcType.kArc3P132) RectanglePoint.Add(P3);
else RectanglePoint.Add(P2);
int[] dx = new int[] { 0, -1, 0, 1 };
int[] dy = new int[] { 1, 0, -1, 0 };
int startQuad = (int)StartAngle / 90;
int endQuad = (int)EndAngle / 90;
int standardQuad = 0;
int iter = 0;
if (Direction == eDirection.CW) {
if (endQuad < 0) standardQuad = endQuad + 4 * ((int)(endQuad / 4) + 1) - 1;
else standardQuad = endQuad;
iter = -endQuad + startQuad;
} else if (Direction == eDirection.CCW) {
if (startQuad < 0) standardQuad = startQuad + 4 * ((int)(startQuad / 4) + 1) - 1;
else standardQuad = startQuad;
iter = endQuad - startQuad;
}
//else;
if (startQuad != endQuad) {
if (iter < 0) iter = iter + 4;
for (int i = 0; i < iter; i++) {
int index = (standardQuad + i) % 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);
//else 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", 7, 7)] // <20><><EFBFBD><EFBFBD> <20>۾<EFBFBD> <20><><EFBFBD><EFBFBD>
[Description("Enable Mark")] // <20><><EFBFBD><EFBFBD> <20>۾<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
public bool Enabled {
get { return m_enabled; }
set { m_enabled = 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>")]
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>")]
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))]
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")]
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")]
public int AlignID {
get { return m_alignID; }
set { m_alignID = value; }
}
#endregion
#region <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>ü<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>Ӽ<EFBFBD>
int m_no;
[Browsable(false)]
public int No {
get { return m_no; }
set { m_no = value; }
}
string m_objectType;
[Browsable(false)]
[ReadOnly(true)]
[Category("<22><>ü")]
[DisplayName("<22><><EFBFBD><EFBFBD>")]
[Description("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ü <20><><EFBFBD><EFBFBD>")]
public string Type {
get {
m_objectType = Arc3Point.ObjectType;
return m_objectType;
}
set { m_objectType = value; }
}
[Browsable(true)]
[ReadOnly(false)]
[CustomSortedCategory("Geometry", 3, 6)]
[CustomSortedDisplayName("Center[X,Y](mm)", 1, 7)]
[Description("Center Of Drawing Object")]
[TypeConverter(typeof(PointFConverter))]
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, 7)]
[Description("Radius Of Arc")]
public float Radius {
get { return m_radius; }
set {
m_radius = value;
P1 = HitUtil.PointOncircle(m_center, m_radius, HitUtil.DegressToRadians(m_startAngle));
P3 = HitUtil.PointOncircle(m_center, m_radius, HitUtil.DegressToRadians(m_endAngle));
}
}
[Browsable(false)]
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, 7)]
[Description("Start Angle")]
public float StartAngle {
get { return m_startAngle; }
set {
m_startAngle = value;
P1 = HitUtil.PointOncircle(m_center, m_radius, HitUtil.DegressToRadians(value));
}
}
[Browsable(false)]
[ReadOnly(false)]
[Category("Geometry")]
[DisplayName("End Angle")]
[Description("End Angle")]
public float EndAngle {
get { return m_endAngle; }
set {
m_endAngle = value;
P3 = HitUtil.PointOncircle(m_center, m_radius, HitUtil.DegressToRadians(value));
}
}
[Browsable(false)]
[ReadOnly(false)]
[CustomSortedCategory("Geometry", 3, 6)]
[CustomSortedDisplayName("Start Point [X,Y](mm)", 1, 3)]
[Description("Start Point")]
[TypeConverter(typeof(PointFConverter))]
public PointF PF1 {
get {
return P1.Point;
}
set {
P1 = new UnitPoint(value);
UpdateArcFrom3Points();
}
}
[Browsable(false)]
[ReadOnly(false)]
[CustomSortedCategory("Geometry", 3, 6)]
[CustomSortedDisplayName("End Point [X,Y](mm)", 1, 3)]
[Description("End Point")]
[TypeConverter(typeof(PointFConverter))]
public PointF PF2 {
get {
return P3.Point;
}
set {
P3 = new UnitPoint(value);
UpdateArcFrom3Points();
}
}
eDirection m_direction = eDirection.CCW;
[Browsable(true)]
[ReadOnly(false)]
[CustomSortedCategory("Geometry", 3, 6)]
[CustomSortedDisplayName("Direction", 5, 7)]
[Description("unit : CW(ClockWise) / CCW(CounterClockWise)")]
public eDirection Direction {
get { return m_direction; }
set { m_direction = value; }
}
bool m_reverse = false;
[Browsable(true)]
[ReadOnly(false)]
[CustomSortedCategory("Geometry", 3, 6)]
[CustomSortedDisplayName("Reverse", 5, 7)]
[Description("Reverse")]
public bool Reverse {
get { return m_reverse; }
set { m_reverse = value; }
}
bool m_lock = false;
[Browsable(true)]
[ReadOnly(false)]
[CustomSortedCategory("Geometry", 3, 6)]
[CustomSortedDisplayName("Lock", 6, 7)]
[Description("Lock")]
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", 7, 7)]
[Description("RCC Arc Mode")]
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; }
}
[Browsable(false)]
public static string ObjectType {
get { return "Arc3p"; }
}
#endregion
//PointF m_PF1;
//PointF m_PF2;
float m_angle;
[Browsable(false)]
public float Angle {
get {
return StartAngle - EndAngle;
}
set {
m_angle = (float)value;
}
}
public virtual IDrawObject Clone()
{
Arc3Point a = new Arc3Point(m_type);
a.Copy(this);
return a;
}
public RectangleF GetBoundingRect(ICanvas canvas)
{
float thWidth = Line.ThresholdWidth(canvas, Width, ThresholdPixel);
if (thWidth < Width)
thWidth = Width;
RectangleF rect = RectangleF.Empty;
// if one of the points is empty, then a straight line is drawn, so return bounding rect for a line
if (m_p2.IsEmpty || m_p3.IsEmpty)
rect = ScreenUtils.GetRect(m_p1, m_lastPoint, thWidth);
if (rect.IsEmpty) {
float r = m_radius + thWidth / 2;
rect = HitUtil.CircleBoundingRect(m_center, r);
if (Selected) {
float w = (float)canvas.ToUnit(20); // include space for the 'extern' nodes
rect.Inflate(w, w);
}
}
// if drawing either angle then include the mouse point in the rectangle - this is to redraw (erase) the line drawn
// from center point to mouse point
//if (m_curPoint == eCurrentPoint.startAngle || m_curPoint == eCurrentPoint.endAngle)
if (m_lastPoint.IsEmpty == false)
rect = RectangleF.Union(rect, new RectangleF(m_lastPoint.Point, new SizeF(0, 0)));
return rect;
}
void DrawArc(ICanvas canvas, RectangleF unitrect)
{
Color color = WeldingParameterIDEditor.weldingColorList[(int)WeldingParameterID - 1];
Pen pen = canvas.CreatePen(color, Width);
bool inline = PointsInLine();
double sweep = GetSweep(StartAngle, EndAngle, Direction);
if (inline == false) {
canvas.DrawArc(canvas, pen, m_center, m_radius, StartAngle, (float)sweep);
if (m_direction == eDirection.CCW) {
DrawUtils.DrawArrowNode(canvas, P3, EndAngle + 90, pen);
} else {
DrawUtils.DrawArrowNode(canvas, P3, EndAngle - 90, pen);
}
} else {
canvas.DrawLine(canvas, pen, P1, P2);
canvas.DrawLine(canvas, pen, P1, P3);
}
if (Selected) {
if (inline == false) {
canvas.DrawArc(canvas, DrawUtils.SelectedPen, m_center, m_radius, StartAngle, (float)sweep);
} else {
canvas.DrawLine(canvas, DrawUtils.SelectedPen, P1, P2);
canvas.DrawLine(canvas, DrawUtils.SelectedPen, P1, P3);
}
if (m_p1.IsEmpty == false) {
DrawUtils.DrawNode(canvas, P1);
UnitPoint anglepoint = StartAngleNodePoint(canvas);
if (!anglepoint.IsEmpty)
DrawUtils.DrawTriangleNode(canvas, anglepoint);
anglepoint = EndAngleNodePoint(canvas);
if (!anglepoint.IsEmpty)
DrawUtils.DrawTriangleNode(canvas, anglepoint);
anglepoint = RadiusNodePoint(canvas);
if (!anglepoint.IsEmpty)
DrawUtils.DrawTriangleNode(canvas, anglepoint);
}
if (m_p2.IsEmpty == false)
DrawUtils.DrawNode(canvas, P2);
if (m_p3.IsEmpty == false)
DrawUtils.DrawNode(canvas, P3);
}
}
bool PointsInLine()
{
double slope1 = HitUtil.LineSlope(P1, P2);
double slope2 = HitUtil.LineSlope(P1, P3);
return slope1 == slope2;
}
void Draw3P132(ICanvas canvas, RectangleF unitrect)
{
Color color = WeldingParameterIDEditor.weldingColorList[(int)WeldingParameterID - 1];
if (m_curPoint == eCurrentPoint.p3) {
Pen pen = canvas.CreatePen(color, Width);
canvas.DrawLine(canvas, pen, m_p1, m_p3);
}
if (m_curPoint == eCurrentPoint.p2 || m_curPoint == eCurrentPoint.done) {
DrawArc(canvas, unitrect);
}
}
void Draw3P123(ICanvas canvas, RectangleF unitrect)
{
Color color = WeldingParameterIDEditor.weldingColorList[(int)WeldingParameterID - 1];
if (m_curPoint == eCurrentPoint.p2) {
Pen pen = canvas.CreatePen(color, Width);
canvas.DrawLine(canvas, pen, m_p1, m_p2);
}
if (m_curPoint == eCurrentPoint.p3 || m_curPoint == eCurrentPoint.done) {
DrawArc(canvas, unitrect);
}
}
public virtual void Draw(ICanvas canvas, RectangleF unitrect)
{
if (m_type == eArcType.kArc3P132)
Draw3P132(canvas, unitrect);
if (m_type == eArcType.kArc3P123)
Draw3P123(canvas, unitrect);
}
public void UpdateCenterNodeFromAngles()
{
float angle = StartAngle + SweepAngle / 2;
P2 = HitUtil.PointOncircle(m_center, m_radius, HitUtil.DegressToRadians(angle));
}
public void UpdateArcFrom3Points()
{
m_center = HitUtil.CenterPointFrom3Points(m_p1, m_p2, m_p3);
m_radius = (float)HitUtil.Distance(m_center, m_p1);
m_startAngle = (float)HitUtil.RadiansToDegrees(HitUtil.LineAngleR(m_center, m_p1, 0));
m_endAngle = (float)HitUtil.RadiansToDegrees(HitUtil.LineAngleR(m_center, m_p3, 0));
// find angle from P1 on line P1|P3 to P2. If this angle is 0-180 the direction is CCW else it is CW
double includeAngle = (float)HitUtil.RadiansToDegrees(HitUtil.LineAngleR(m_center, m_p2, 0));
// double p1p3angle = HitUtil.RadiansToDegrees(HitUtil.LineAngleR(m_p1, m_p3, 0));
//double p1p2angle = HitUtil.RadiansToDegrees(HitUtil.LineAngleR(m_p1, m_p2, 0));
//double diff = p1p3angle - p1p2angle;
// I know there is a problem with this logic, in some cases the arc does not follow the mouse,
// but it will work for now.
/* if (m_startAngle > includeAngle)
{
if ((m_endAngle - m_startAngle) * (m_endAngle - includeAngle) > 0)
{
m_direction = eDirection.CW;
}
else
{
m_direction = eDirection.CCW;
}
}
else
{
if ((m_endAngle - m_startAngle) * (m_endAngle - includeAngle) > 0)
{
m_direction = eDirection.CCW;
}
else
{
m_direction = eDirection.CW;
}
}*/
// Direction = eDirection.kCCW;
//if (diff < 0 || diff > 180)
// Direction = eDirection.kCW;
//if (p1p3angle == 0)
//{
// if (diff < -180)
// Direction = eDirection.kCCW;
// else
// Direction = eDirection.kCW;
//}
//if (p1p3angle == 90)
//{
// if (diff < -180)
// Direction = eDirection.kCCW;
//}
}
void MoveMouse3P132(ICanvas canvas, UnitPoint point)
{
if (m_curPoint == eCurrentPoint.p1) {
P2 = point;
return;
}
if (m_curPoint == eCurrentPoint.p3) {
m_p3 = point;
return;
}
if (m_curPoint == eCurrentPoint.p2) {
m_p2 = point;
UpdateArcFrom3Points();
return;
}
}
void MoveMouse3P123(ICanvas canvas, UnitPoint point)
{
if (m_curPoint == eCurrentPoint.p1) {
m_p1 = point;
return;
}
if (m_curPoint == eCurrentPoint.p2) {
m_p2 = point;
return;
}
if (m_curPoint == eCurrentPoint.p3) {
m_p3 = point;
UpdateArcFrom3Points();
return;
}
}
eDrawObjectMouseDown MouseDown3P132(ICanvas canvas, UnitPoint point, ISnapPoint snappoint)
{
OnMouseMove(canvas, point);
if (m_curPoint == eCurrentPoint.p1) {
m_curPoint = eCurrentPoint.p3;
return eDrawObjectMouseDown.Continue;
}
if (m_curPoint == eCurrentPoint.p3) {
m_curPoint = eCurrentPoint.p2;
return eDrawObjectMouseDown.Continue;
}
if (m_curPoint == eCurrentPoint.p2) {
m_curPoint = eCurrentPoint.done;
Selected = false;
return eDrawObjectMouseDown.Done;
}
return eDrawObjectMouseDown.Done;
}
eDrawObjectMouseDown MouseDown3P123(ICanvas canvas, UnitPoint point, ISnapPoint snappoint)
{
OnMouseMove(canvas, point);
if (m_curPoint == eCurrentPoint.p1) {
m_curPoint = eCurrentPoint.p2;
return eDrawObjectMouseDown.Continue;
}
if (m_curPoint == eCurrentPoint.p2) {
m_curPoint = eCurrentPoint.p3;
return eDrawObjectMouseDown.Continue;
}
if (m_curPoint == eCurrentPoint.p3) {
m_curPoint = eCurrentPoint.done;
Selected = false;
return eDrawObjectMouseDown.Done;
}
return eDrawObjectMouseDown.Done;
}
UnitPoint StartAngleNodePoint(ICanvas canvas)
{
double r = Radius + canvas.ToUnit(8);
return HitUtil.PointOncircle(m_center, r, HitUtil.DegressToRadians(StartAngle));
}
UnitPoint EndAngleNodePoint(ICanvas canvas)
{
double r = Radius + canvas.ToUnit(8);
return HitUtil.PointOncircle(m_center, r, HitUtil.DegressToRadians(EndAngle));
}
UnitPoint RadiusNodePoint(ICanvas canvas)
{
double r = Radius + canvas.ToUnit(8);
float angle = StartAngle + SweepAngle / 2;
return HitUtil.PointOncircle(m_center, r, HitUtil.DegressToRadians(angle));
}
public virtual void OnMouseMove(ICanvas canvas, UnitPoint point)
{
//m_lastPoint = point;
if (m_type == eArcType.kArc3P132)
MoveMouse3P132(canvas, point);
if (m_type == eArcType.kArc3P123)
MoveMouse3P123(canvas, point);
}
public virtual eDrawObjectMouseDown OnMouseDown(ICanvas canvas, UnitPoint point, ISnapPoint snappoint)
{
if (m_type == eArcType.kArc3P132)
return MouseDown3P132(canvas, point, snappoint);
if (m_type == eArcType.kArc3P123)
return MouseDown3P123(canvas, point, snappoint);
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) {
if (Direction == eDirection.CW)
Direction = eDirection.CCW;
else
Direction = eDirection.CW;
e.Handled = true;
}
}
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.IsPointInCircle(m_center, m_radius, point, thWidth / 2);
}
public virtual bool ObjectInRectangle(ICanvas canvas, RectangleF rect, bool anyPoint)
{
float r = m_radius + Width / 2;
RectangleF boundingrect = HitUtil.CircleBoundingRect(m_center, r);
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)]
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(P1, point, thWidth)) {
m_lastPoint = P1;
return new NodePointArc3PointPoint(this, eCurrentPoint.p1);
}
if (HitUtil.PointInPoint(P2, point, thWidth)) {
m_lastPoint = P2;
return new NodePointArc3PointPoint(this, eCurrentPoint.p2);
}
if (HitUtil.PointInPoint(P3, point, thWidth)) {
m_lastPoint = P3;
return new NodePointArc3PointPoint(this, eCurrentPoint.p3);
}
UnitPoint p = StartAngleNodePoint(canvas);
if (HitUtil.PointInPoint(p, point, thWidth)) {
m_lastPoint = p;
return new NodePointArc3PointPoint(this, eCurrentPoint.startangle);
}
p = EndAngleNodePoint(canvas);
if (HitUtil.PointInPoint(p, point, thWidth)) {
m_lastPoint = p;
return new NodePointArc3PointPoint(this, eCurrentPoint.endangle);
}
p = RadiusNodePoint(canvas);
if (HitUtil.PointInPoint(p, point, thWidth)) {
m_lastPoint = p;
return new NodePointArc3PointPoint(this, eCurrentPoint.radius);
}
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(CenterSnapPoint))
{
if (HitUtil.PointInPoint(m_center, point, thWidth))
return new CenterSnapPoint(canvas, this, m_center);
}
* */
if (snaptype == typeof(VertextSnapPoint)) {
if (HitUtil.PointInPoint(P1, point, thWidth))
return new VertextSnapPoint(canvas, this, P1);
if (HitUtil.PointInPoint(P3, point, thWidth))
return new VertextSnapPoint(canvas, this, P3);
}
}
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(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)
{
P1 += offset;
P2 += offset;
P3 += offset;
UpdateArcFrom3Points();
m_lastPoint = m_center;
}
public void Rotate(float angle, UnitPoint center)
{
m_p1 = HitUtil.RotatePoint(angle, m_p1, center);
m_p2 = HitUtil.RotatePoint(angle, m_p2, center);
m_p3 = HitUtil.RotatePoint(angle, m_p3, center);
UpdateArcFrom3Points();
}
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()
{
UpdateArcFrom3Points();
}
#endregion
protected static int ThresholdPixel = 6;
public enum eCurrentPoint
{
p1,
p2,
p3,
startangle,
endangle,
radius,
done,
}
[Browsable(false)]
public eCurrentPoint CurrentPoint {
get { return m_curPoint; }
set { m_curPoint = value; }
}
protected eCurrentPoint m_curPoint = eCurrentPoint.p1;
protected UnitPoint m_lastPoint = UnitPoint.Empty;
}
}