1458 lines
49 KiB
C#
1458 lines
49 KiB
C#
using CoreUnit.Common;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Drawing;
|
||
using System.Text.Json;
|
||
using System.Windows.Forms;
|
||
using System.Xml;
|
||
|
||
namespace CoreUnit.Control.UserControl.Canvas
|
||
{
|
||
public class SnowMan : DrawObjectBase, IDrawObject, ISerialize
|
||
{
|
||
UnitPoint m_p1, m_p2;
|
||
|
||
[Browsable(false)]
|
||
public UnitPoint Center {
|
||
get { return new UnitPoint(MiddlePoint); }
|
||
set { MiddlePoint = ((UnitPoint)value).Point; }
|
||
}
|
||
|
||
[Browsable(false)]
|
||
public UnitPoint P1 {
|
||
get { return m_p1; }
|
||
set { m_p1 = value; }
|
||
}
|
||
|
||
[Browsable(false)]
|
||
public UnitPoint P2 {
|
||
get { return m_p2; }
|
||
set { m_p2 = value; }
|
||
}
|
||
|
||
public static string ObjectType {
|
||
get { return "SnowMan"; }
|
||
}
|
||
|
||
public SnowMan()
|
||
{
|
||
}
|
||
|
||
public SnowMan(UnitPoint point, UnitPoint endpoint, float width, Color color)
|
||
{
|
||
P1 = point;
|
||
P2 = endpoint;
|
||
Width = width;
|
||
Color = color;
|
||
Selected = false;
|
||
|
||
m_circumferenceHead = CalculateCircumference(Rh1, Rw1);
|
||
m_circumferenceBody = CalculateCircumference(Rh2, Rw2);
|
||
CreateWobbelVectorPointList();
|
||
}
|
||
|
||
public override void InitializeFromModel(UnitPoint point, DrawingLayer layer, ISnapPoint snap)
|
||
{
|
||
P1 = P2 = point;
|
||
Width = layer.Width;
|
||
Color = layer.Color;
|
||
Selected = true;
|
||
}
|
||
|
||
static int ThresholdPixel = 6;
|
||
static float ThresholdWidth(ICanvas canvas, float objectwidth)
|
||
{
|
||
return ThresholdWidth(canvas, objectwidth, ThresholdPixel);
|
||
}
|
||
|
||
public static float ThresholdWidth(ICanvas canvas, float objectwidth, float pixelwidth)
|
||
{
|
||
double minWidth = canvas.ToUnit(pixelwidth);
|
||
double width = Math.Max(objectwidth / 2, minWidth);
|
||
return (float)width;
|
||
}
|
||
|
||
public virtual void Copy(SnowMan acopy)
|
||
{
|
||
base.Copy(acopy);
|
||
P1 = acopy.P1;
|
||
P2 = acopy.P2;
|
||
Type = acopy.Type;
|
||
m_no = acopy.m_no;
|
||
|
||
//<2F><>ŷ<EFBFBD><C5B7>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD> <20>Ӽ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
ScannerParamNo = acopy.ScannerParamNo;
|
||
Enabled = acopy.Enabled;
|
||
Selected = acopy.Selected;
|
||
|
||
//Snowman <20>Ӽ<EFBFBD>
|
||
TiltingAngle = acopy.TiltingAngle;
|
||
m_horizontalRadiusofHead = acopy.Rh1;
|
||
m_verticalRadiusofHead = acopy.Rw1;
|
||
m_horizontalRadiusofBody = acopy.Rh2;
|
||
m_verticalRadiusofBody = acopy.Rw2;
|
||
m_velocityOfHead = acopy.HeadSpeed;
|
||
m_velocityOfBody = acopy.BodySpeed;
|
||
m_controlType = acopy.ControlType;
|
||
m_drawWay = acopy.DrawWay;
|
||
m_vectorCount = acopy.VectorCount;
|
||
|
||
m_circumferenceHead = CalculateCircumference(Rh1, Rw1);
|
||
m_circumferenceBody = CalculateCircumference(Rh2, Rw2);
|
||
CreateWobbelVectorPointList();
|
||
}
|
||
#region IDrawObject Members
|
||
|
||
#region <EFBFBD><EFBFBD>ŷ<EFBFBD><EFBFBD>ü<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>Ӽ<EFBFBD>
|
||
bool m_enabled = true;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("3. Marking Parameter")]
|
||
[DisplayName("<22><><EFBFBD><EFBFBD> <20>۾<EFBFBD> <20><><EFBFBD><EFBFBD>")]
|
||
[Description("<22><><EFBFBD><EFBFBD> <20>۾<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>")]
|
||
[XmlSerializable]
|
||
public bool Enabled {
|
||
get { return m_enabled; }
|
||
set { m_enabled = value; }
|
||
}
|
||
|
||
int m_scannerParamNo = 0;
|
||
[Browsable(false)]
|
||
[ReadOnly(false)]
|
||
[Category("3. Marking Parameter")]
|
||
[DisplayName("<22><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ȣ")]
|
||
[Description("<22><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>(<28><>ĵ<EFBFBD>ӵ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ŀ<EFBFBD> <20><><EFBFBD><EFBFBD>..) <20><>ȣ <20><><EFBFBD><EFBFBD>")]
|
||
[XmlSerializable]
|
||
public int ScannerParamNo {
|
||
get { return m_scannerParamNo; }
|
||
set { m_scannerParamNo = value; }
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("3. Marking Parameter")]
|
||
[DisplayName("<22><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ID")]
|
||
[Description("<22><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>(<28><>ĵ<EFBFBD>ӵ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ŀ<EFBFBD> <20><><EFBFBD><EFBFBD>..) ID <20><><EFBFBD><EFBFBD>")]
|
||
[XmlSerializable]
|
||
public int ScannerParamID {
|
||
get { return m_scannerParamNo + 1; }
|
||
set { m_scannerParamNo = value - 1; }
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("Pen")]
|
||
[DisplayName("Parameter ID")]
|
||
[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; }
|
||
}
|
||
#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(true)]
|
||
[ReadOnly(true)]
|
||
[Category("1. <20><>ü")]
|
||
[DisplayName("<22><><EFBFBD><EFBFBD>")]
|
||
[Description("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ü <20><><EFBFBD><EFBFBD>")]
|
||
[XmlSerializable]
|
||
public string Type {
|
||
get {
|
||
m_type = SnowMan.ObjectType;
|
||
return m_type;
|
||
}
|
||
set { m_type = value; }
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("2. GEOMETRY")]
|
||
[DisplayName("1.<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[X,Y](mm)")]
|
||
[Description("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>")]
|
||
[TypeConverter(typeof(PointFConverter))]
|
||
[XmlSerializable]
|
||
public PointF PF1 {
|
||
get { lock (this) { return P1.Point; } }
|
||
set { lock (this) { P1 = new UnitPoint(value); } }
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("2. GEOMETRY")]
|
||
[DisplayName("2.<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[X,Y](mm)")]
|
||
[Description("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>")]
|
||
[TypeConverter(typeof(PointFConverter))]
|
||
[XmlSerializable]
|
||
public PointF PF2 {
|
||
get { lock (this) { return P2.Point; } }
|
||
set { lock (this) { P2 = new UnitPoint(value); } }
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("2. GEOMETRY")]
|
||
[DisplayName("3.<2E>߽<EFBFBD><DFBD><EFBFBD>[X,Y](mm)")]
|
||
[Description("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC> <20>߽<EFBFBD><DFBD><EFBFBD>")]
|
||
[TypeConverter(typeof(PointFConverter))]
|
||
public PointF MiddlePoint {
|
||
get { return HitUtil.LineMidpoint(P1, P2).Point; }
|
||
set {
|
||
PointF offset = new PointF();
|
||
offset.X = (value.X - MiddlePoint.X);
|
||
offset.Y = (value.Y - MiddlePoint.Y);
|
||
Move(new UnitPoint(offset));
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("2. GEOMETRY")]
|
||
[DisplayName("4.<2E><><EFBFBD><EFBFBD>(<28><>)")]
|
||
[Description("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD>")]
|
||
public float Angle {
|
||
get { return (float)Math.Round(HitUtil.RadiansToDegrees(HitUtil.LineAngleR(P1, P2, 0)), 3); }
|
||
set {
|
||
float angle = value - Angle;
|
||
Rotate(angle, Center);
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(true)]
|
||
[Category("Boundary")]
|
||
[DisplayName("Left,Bottom,Right,Top")]
|
||
[Description("Boundary of Object")]
|
||
[TypeConverter(typeof(RectangleFConverter))]
|
||
public RectangleF ClientRect {
|
||
get {
|
||
lock (this) { return ScreenUtils.GetRect(P1, P2, 0); }
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("2. GEOMETRY")]
|
||
[DisplayName("6.<2E><><EFBFBD><EFBFBD>(mm)")]
|
||
[Description("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD>")]
|
||
public double Distance {
|
||
get { return Math.Round(HitUtil.Distance(P1, P2), 3); }
|
||
set {
|
||
double distance = value;
|
||
MakeLength((float)distance);
|
||
}
|
||
}
|
||
|
||
double m_tiltingAngle = 0;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("3. SnowMan")]
|
||
[DisplayName("01.Angle(degree)")]
|
||
[Description("Tilting Angle of SnowMan by degree")]
|
||
[XmlSerializable]
|
||
public double TiltingAngle {
|
||
get { return m_tiltingAngle; }
|
||
set { m_tiltingAngle = value; }
|
||
}
|
||
|
||
double m_horizontalRadiusofHead = 1;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("3. SnowMan")]
|
||
[DisplayName("02.Rh1(mm)")]
|
||
[Description("Horizontal Radius of Head Ellipse(0.1mm ~ 10mm)")]
|
||
[XmlSerializable]
|
||
public double Rh1 {
|
||
get { return m_horizontalRadiusofHead; }
|
||
set {
|
||
m_horizontalRadiusofHead = value;
|
||
m_circumferenceHead = CalculateCircumference(m_horizontalRadiusofHead, m_verticalRadiusofHead);
|
||
CreateWobbelVectorPointList();
|
||
}
|
||
}
|
||
|
||
double m_verticalRadiusofHead = 1;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("3. SnowMan")]
|
||
[DisplayName("03.Rw1(mm)")]
|
||
[Description("Vertical Radius of Head Ellipse(0.1mm ~ 10mm)")]
|
||
[XmlSerializable]
|
||
public double Rw1 {
|
||
get { return m_verticalRadiusofHead; }
|
||
set {
|
||
m_verticalRadiusofHead = value;
|
||
m_circumferenceHead = CalculateCircumference(m_horizontalRadiusofHead, m_verticalRadiusofHead);
|
||
CreateWobbelVectorPointList();
|
||
}
|
||
}
|
||
|
||
double m_horizontalRadiusofBody = 1;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("3. SnowMan")]
|
||
[DisplayName("04.Rh2(mm)")]
|
||
[Description("Horizontal Radius of Body Ellipse(0.1mm ~ 10mm)")]
|
||
[XmlSerializable]
|
||
public double Rh2 {
|
||
get { return m_horizontalRadiusofBody; }
|
||
set {
|
||
m_horizontalRadiusofBody = value;
|
||
m_circumferenceBody = CalculateCircumference(m_horizontalRadiusofBody, m_verticalRadiusofBody);
|
||
CreateWobbelVectorPointList();
|
||
}
|
||
}
|
||
|
||
double m_verticalRadiusofBody = 1;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("3. SnowMan")]
|
||
[DisplayName("05.Rw2(mm)")]
|
||
[Description("Vertical Radius of Body Ellipse(0.1mm ~ 10mm)")]
|
||
[XmlSerializable]
|
||
public double Rw2 {
|
||
get { return m_verticalRadiusofBody; }
|
||
set {
|
||
m_verticalRadiusofBody = value;
|
||
m_circumferenceBody = CalculateCircumference(m_horizontalRadiusofBody, m_verticalRadiusofBody);
|
||
CreateWobbelVectorPointList();
|
||
}
|
||
}
|
||
|
||
double m_velocityOfHead = 1;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("3. SnowMan")]
|
||
[DisplayName("06.Head Speed")]
|
||
[Description("Angular Speed Control : deg/s\nLine Speed Control : mm/s")]
|
||
[XmlSerializable]
|
||
public double HeadSpeed {
|
||
get { return m_velocityOfHead; }
|
||
set {
|
||
m_velocityOfHead = value;
|
||
|
||
CreateWobbelVectorPointList();
|
||
}
|
||
}
|
||
|
||
double m_velocityOfBody = 1;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("3. SnowMan")]
|
||
[DisplayName("07.Body Speed")]
|
||
[Description("Angular Speed Control : deg/s\nLine Speed Control : mm/s")]
|
||
[XmlSerializable]
|
||
public double BodySpeed {
|
||
get { return m_velocityOfBody; }
|
||
set {
|
||
m_velocityOfBody = value;
|
||
CreateWobbelVectorPointList();
|
||
}
|
||
}
|
||
|
||
public enum eControlType
|
||
{
|
||
AngularSpeedControl = 1,
|
||
LineSpeedControl = 2
|
||
}
|
||
|
||
eControlType m_controlType = eControlType.AngularSpeedControl;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("3. SnowMan")]
|
||
[DisplayName("08.Control Type")]
|
||
[Description("Control Type(Angular or Line)")]
|
||
[XmlSerializable]
|
||
public eControlType ControlType {
|
||
get { return m_controlType; }
|
||
set {
|
||
m_controlType = value;
|
||
|
||
CreateWobbelVectorPointList();
|
||
|
||
}
|
||
}
|
||
|
||
public enum eDrawWay
|
||
{
|
||
Left = 1,
|
||
Right = 2
|
||
}
|
||
|
||
eDrawWay m_drawWay = eDrawWay.Left;
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("3. SnowMan")]
|
||
[DisplayName("09.Draw Way")]
|
||
[Description("Draw Way(Left or Right)")]
|
||
[XmlSerializable]
|
||
public eDrawWay DrawWay {
|
||
get { return m_drawWay; }
|
||
set {
|
||
m_drawWay = value;
|
||
|
||
CreateWobbelVectorPointList();
|
||
|
||
}
|
||
}
|
||
|
||
double m_circumferenceHead = 1;
|
||
[Browsable(true)]
|
||
[ReadOnly(true)]
|
||
[Category("3. SnowMan")]
|
||
[DisplayName("10.Ch")]
|
||
[Description("Circumference length of Head")]
|
||
public double Ch {
|
||
get { return m_circumferenceHead; }
|
||
}
|
||
|
||
double m_circumferenceBody = 1;
|
||
[Browsable(true)]
|
||
[ReadOnly(true)]
|
||
[Category("3. SnowMan")]
|
||
[DisplayName("11.Cb")]
|
||
[Description("Circumference length of Body")]
|
||
public double Cb {
|
||
get { return m_circumferenceBody; }
|
||
}
|
||
|
||
private double CalculateCircumference(double a, double b)
|
||
{
|
||
|
||
//Ÿ<><C5B8><EFBFBD><EFBFBD> <20>ѷ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ϱ<EFBFBD>
|
||
//Ÿ<><C5B8><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ϲ<EFBFBD><CFB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><> <20><><EFBFBD><EFBFBD>, <20>ٻ簪<D9BB><E7B0AA><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
int iterationCount = 100000;
|
||
double dx = a / iterationCount;
|
||
double sum = 0;
|
||
for (int i = 0; i < iterationCount - 1; i++) {
|
||
double x = (i + 1) * dx;
|
||
sum += dx * Math.Sqrt(1 + Math.Pow(b / a, 2) * Math.Pow(x, 2) / (Math.Pow(a, 2) - Math.Pow(x, 2)));
|
||
}
|
||
|
||
return 4 * sum;
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(true)]
|
||
[Category("3. SnowMan")]
|
||
[DisplayName("13.Cycle Time of Head")]
|
||
[Description("Cycle Time of Head")]
|
||
public double HeadCycleTime {
|
||
get {
|
||
if (ControlType == eControlType.AngularSpeedControl) {
|
||
return 360 / HeadSpeed;
|
||
} else {
|
||
return Ch / HeadSpeed;
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(true)]
|
||
[Category("3. SnowMan")]
|
||
[DisplayName("14.Cycle Time of Body")]
|
||
[Description("Cycle Time of Body")]
|
||
public double BodyCycleTime {
|
||
get {
|
||
if (ControlType == eControlType.AngularSpeedControl) {
|
||
return 360 / BodySpeed;
|
||
} else {
|
||
return Cb / BodySpeed;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(true)]
|
||
[Category("3. SnowMan")]
|
||
[DisplayName("15.Cycle Time of SnowMan")]
|
||
[Description("Cycle Time of SnowMan")]
|
||
public double SnowManCycleTime {
|
||
get { return HeadCycleTime + BodyCycleTime; }
|
||
}
|
||
|
||
eVectorCount m_vectorCount = eVectorCount.C200;
|
||
public enum eVectorCount
|
||
{
|
||
C50 = 50, C100 = 100, C150 = 150, C200 = 200
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(false)]
|
||
[Category("3. SnowMan")]
|
||
[DisplayName("16.Vector Count")]
|
||
[Description("Head And Body can have Upto 256 Count")]
|
||
[XmlSerializable]
|
||
public eVectorCount VectorCount {
|
||
get { return m_vectorCount; }
|
||
set {
|
||
m_vectorCount = value;
|
||
CreateWobbelVectorPointList();
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(true)]
|
||
[Category("4. Head Wobbel Vector")]
|
||
[DisplayName("1.Period")]
|
||
[Description("period per Vector")]
|
||
public double HeadPeriod {
|
||
get { return (HeadCycleTime / (int)VectorCount) * 100 * 1000; }
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(true)]
|
||
[Category("4. Head Wobbel Vector")]
|
||
[DisplayName("2.Vector Angle")]
|
||
[Description("Vector Angle")]
|
||
public double HeadVectorAngle {
|
||
get { return 2 * Math.PI / (int)VectorCount; }
|
||
}
|
||
|
||
protected List<PointF> m_headPoint = new List<PointF>();
|
||
[Browsable(true)]
|
||
[ReadOnly(true)]
|
||
[Category("4. Head Wobbel Vector")]
|
||
[DisplayName("3.Head Point")]
|
||
[Description("X : dTrans, Y: dLong")]
|
||
public List<PointF> HeadPoint {
|
||
get { return m_headPoint; }
|
||
set { m_headPoint = value; }
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(true)]
|
||
[Category("5. Body Wobbel Vector")]
|
||
[DisplayName("1.Period")]
|
||
[Description("period per Vector")]
|
||
public double BodyPeriod {
|
||
get { return (BodyCycleTime / (int)VectorCount) * 100 * 1000; }
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[ReadOnly(true)]
|
||
[Category("5. Body Wobbel Vector")]
|
||
[DisplayName("2.Vector Angle")]
|
||
[Description("Vector Angle")]
|
||
public double BodyVectorAngle {
|
||
get { return 2 * Math.PI / (int)VectorCount; }
|
||
}
|
||
|
||
protected List<PointF> m_bodyPoint = new List<PointF>();
|
||
[Browsable(true)]
|
||
[ReadOnly(true)]
|
||
[Category("5. Body Wobbel Vector")]
|
||
[DisplayName("3.Body Point")]
|
||
[Description("X : dTrans, Y: dLong")]
|
||
public List<PointF> BodyPoint {
|
||
get { return m_bodyPoint; }
|
||
set { m_bodyPoint = value; }
|
||
}
|
||
|
||
private void CreateWobbelVectorPointList()
|
||
{
|
||
m_headPoint.Clear();
|
||
m_bodyPoint.Clear();
|
||
|
||
double xPoint = 0;
|
||
double yPoint = 0;
|
||
double radius = 0;
|
||
|
||
//<2F><><EFBFBD>ӵ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
if (ControlType == eControlType.AngularSpeedControl) {
|
||
m_headPoint.Add(new PointF(0, 0));
|
||
m_bodyPoint.Add(new PointF(0, 0));
|
||
|
||
//Head Wobbel vector <20><><EFBFBD><EFBFBD>
|
||
for (int i = 0; i < (int)VectorCount; i++) {
|
||
double term1 = (Math.Pow(Math.Cos((i + 1) * HeadVectorAngle), 2)) / (Math.Pow(Rh1, 2));
|
||
double term2 = (Math.Pow(Math.Sin((i + 1) * HeadVectorAngle), 2)) / (Math.Pow(Rw1, 2));
|
||
|
||
radius = Math.Sqrt(1 / (term1 + term2));
|
||
|
||
|
||
if (DrawWay == eDrawWay.Left) {
|
||
xPoint = radius * Math.Cos((i + 1) * HeadVectorAngle) - Rh1;
|
||
yPoint = radius * Math.Sin((i + 1) * HeadVectorAngle);
|
||
} else {
|
||
xPoint = radius * Math.Cos(Math.PI - (i + 1) * HeadVectorAngle) + Rh1;
|
||
yPoint = radius * Math.Sin(Math.PI - (i + 1) * HeadVectorAngle);
|
||
}
|
||
|
||
|
||
m_headPoint.Add(new PointF((float)xPoint, (float)yPoint));
|
||
|
||
}
|
||
|
||
//body Wobbel vector <20><><EFBFBD><EFBFBD>
|
||
for (int i = 0; i < (int)VectorCount; i++) {
|
||
double term1 = (Math.Pow(Math.Cos((i + 1) * BodyVectorAngle), 2)) / (Math.Pow(Rh2, 2));
|
||
double term2 = (Math.Pow(Math.Sin((i + 1) * BodyVectorAngle), 2)) / (Math.Pow(Rw2, 2));
|
||
|
||
radius = Math.Sqrt(1 / (term1 + term2));
|
||
|
||
if (DrawWay == eDrawWay.Left) {
|
||
xPoint = radius * Math.Cos(Math.PI - (i + 1) * BodyVectorAngle) + Rh2;
|
||
yPoint = radius * Math.Sin(Math.PI - (i + 1) * BodyVectorAngle);
|
||
} else {
|
||
xPoint = radius * Math.Cos((i + 1) * BodyVectorAngle) - Rh2;
|
||
yPoint = radius * Math.Sin((i + 1) * BodyVectorAngle);
|
||
|
||
}
|
||
|
||
|
||
m_bodyPoint.Add(new PointF((float)xPoint, (float)yPoint));
|
||
}
|
||
} else {
|
||
if (DrawWay == eDrawWay.Left) {
|
||
//Head
|
||
m_headPoint.Add(new PointF(0, 0));
|
||
|
||
xLower = -2 * Rh1;
|
||
xUpper = 0;
|
||
|
||
int quadrant = 2;
|
||
|
||
for (int i = 0; i < (int)VectorCount / 2 - 1; i++) {
|
||
double x2, y2;
|
||
x2 = FindX2(m_headPoint[i].X, m_headPoint[i].Y, Rh1, Rw1, Ch / (int)VectorCount, quadrant);
|
||
|
||
y2 = FindY2(x2, quadrant, Rh1, Rw1);
|
||
m_headPoint.Add(new PointF((float)x2, (float)y2));
|
||
|
||
}
|
||
|
||
|
||
m_headPoint.Add(new PointF((float)(-2 * Rh1), 0));
|
||
|
||
xLower = -2 * Rh1;
|
||
xUpper = 0;
|
||
|
||
quadrant = 3;
|
||
|
||
for (int i = (int)VectorCount / 2; i < (int)VectorCount; i++) {
|
||
double x2, y2;
|
||
x2 = FindX2(m_headPoint[i].X, m_headPoint[i].Y, Rh1, Rw1, Ch / (int)VectorCount, quadrant);
|
||
y2 = FindY2(x2, quadrant, Rh1, Rw1);
|
||
m_headPoint.Add(new PointF((float)x2, (float)y2));
|
||
}
|
||
|
||
|
||
|
||
// Body
|
||
m_bodyPoint.Add(new PointF(0, 0));
|
||
|
||
xLower = 0;
|
||
xUpper = 2 * Rh2;
|
||
|
||
quadrant = 1;
|
||
|
||
for (int i = 0; i < (int)VectorCount / 2 - 1; i++) {
|
||
double x2, y2;
|
||
x2 = FindX2(m_bodyPoint[i].X, m_bodyPoint[i].Y, Rh2, Rw2, Cb / (int)VectorCount, quadrant);
|
||
y2 = FindY2(x2, quadrant, Rh2, Rw2);
|
||
m_bodyPoint.Add(new PointF((float)x2, (float)y2));
|
||
}
|
||
|
||
m_bodyPoint.Add(new PointF((float)(2 * Rh2), 0));
|
||
|
||
xLower = 0;
|
||
xUpper = 2 * Rh2;
|
||
|
||
quadrant = 4;
|
||
|
||
for (int i = (int)VectorCount / 2; i < (int)VectorCount; i++) {
|
||
double x2, y2;
|
||
x2 = FindX2(m_bodyPoint[i].X, m_bodyPoint[i].Y, Rh2, Rw2, Cb / (int)VectorCount, quadrant);
|
||
y2 = FindY2(x2, quadrant, Rh2, Rw2);
|
||
m_bodyPoint.Add(new PointF((float)x2, (float)y2));
|
||
}
|
||
} else {
|
||
//Head
|
||
m_headPoint.Add(new PointF(0, 0));
|
||
|
||
xLower = 0;
|
||
xUpper = 2 * Rh1;
|
||
|
||
int quadrant = 1;
|
||
|
||
for (int i = 0; i < (int)VectorCount / 2 - 1; i++) {
|
||
double x2, y2;
|
||
x2 = FindX2(m_headPoint[i].X, m_headPoint[i].Y, Rh1, Rw1, Ch / (int)VectorCount, quadrant);
|
||
y2 = FindY2(x2, quadrant, Rh1, Rw1);
|
||
m_headPoint.Add(new PointF((float)x2, (float)y2));
|
||
|
||
}
|
||
|
||
m_headPoint.Add(new PointF((float)(2 * Rh1), 0));
|
||
|
||
xLower = 0;
|
||
xUpper = 2 * Rh1;
|
||
|
||
quadrant = 4;
|
||
|
||
for (int i = (int)VectorCount / 2; i < (int)VectorCount; i++) {
|
||
double x2, y2;
|
||
x2 = FindX2(m_headPoint[i].X, m_headPoint[i].Y, Rh1, Rw1, Ch / (int)VectorCount, quadrant);
|
||
y2 = FindY2(x2, quadrant, Rh1, Rw1);
|
||
m_headPoint.Add(new PointF((float)x2, (float)y2));
|
||
}
|
||
|
||
// Body
|
||
m_bodyPoint.Add(new PointF(0, 0));
|
||
|
||
xLower = -2 * Rh2;
|
||
xUpper = 0;
|
||
|
||
quadrant = 2;
|
||
|
||
for (int i = 0; i < (int)VectorCount / 2 - 1; i++) {
|
||
double x2, y2;
|
||
x2 = FindX2(m_bodyPoint[i].X, m_bodyPoint[i].Y, Rh2, Rw2, Cb / (int)VectorCount, quadrant);
|
||
y2 = FindY2(x2, quadrant, Rh2, Rw2);
|
||
m_bodyPoint.Add(new PointF((float)x2, (float)y2));
|
||
}
|
||
|
||
m_bodyPoint.Add(new PointF((float)(-2 * Rh2), 0));
|
||
|
||
xLower = -2 * Rh2;
|
||
xUpper = 0;
|
||
|
||
quadrant = 3;
|
||
|
||
for (int i = (int)VectorCount / 2; i < (int)VectorCount; i++) {
|
||
double x2, y2;
|
||
x2 = FindX2(m_bodyPoint[i].X, m_bodyPoint[i].Y, Rh2, Rw2, Cb / (int)VectorCount, quadrant);
|
||
y2 = FindY2(x2, quadrant, Rh2, Rw2);
|
||
m_bodyPoint.Add(new PointF((float)x2, (float)y2));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//<2F><>ġ<EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
double xLower = 0;
|
||
double xUpper = 0;
|
||
|
||
private double FindX2(double x1, double y1, double A, double B, double L, int quadrant)
|
||
{
|
||
|
||
int i = 1;
|
||
double xReal = xLower;//ù<><C3B9><EFBFBD><EFBFBD>
|
||
double xRold;
|
||
double error = 0;
|
||
|
||
while (true) {
|
||
double test = Function2(x1, y1, xLower, L, quadrant, A, B) * Function2(x1, y1, xUpper, L, quadrant, A, B);
|
||
if (test > 0) {
|
||
break;
|
||
} else {
|
||
xRold = xReal;
|
||
|
||
xReal = (xLower + xUpper) / 2; //<2F>̺й<CCBA><D0B9><EFBFBD><EFBFBD><EFBFBD> <20>ش<EFBFBD> <20><><EFBFBD><EFBFBD> <20>糡<EFBFBD><E7B3A1> <20><><EFBFBD><EFBFBD>
|
||
error = (xReal - xRold) / xReal; //<2F>ٻ<EFBFBD><D9BB><EFBFBD><EFBFBD><EFBFBD>
|
||
|
||
double test2 = Function2(x1, y1, xReal, L, quadrant, A, B) * Function2(x1, y1, xLower, L, quadrant, A, B);
|
||
|
||
if (test2 < 0) {
|
||
xUpper = xReal;
|
||
} else {
|
||
xLower = xReal;
|
||
}
|
||
|
||
string Check = string.Format("xLower = {0:f3}, xUpper = {1:f3}, xReal = {2:f3}, error = {3:f3}", xLower, xUpper, xReal, error);
|
||
|
||
i = i + 1;
|
||
}
|
||
|
||
if ((i > 1000) || Math.Abs(error) < 0.00001)//iteration <20>ִ<EFBFBD>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD>ϰų<CFB0> Error <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Ż<><C5BB>
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
switch (quadrant) {
|
||
case 1:
|
||
xUpper = 2 * A;
|
||
xLower = xReal;
|
||
break;
|
||
case 2:
|
||
xUpper = xReal;
|
||
xLower = -2 * A;
|
||
break;
|
||
case 3:
|
||
xUpper = 0;
|
||
xLower = xReal;
|
||
break;
|
||
case 4:
|
||
xUpper = xReal;
|
||
xLower = 0;
|
||
break;
|
||
}
|
||
|
||
return xReal;
|
||
|
||
}
|
||
|
||
private double Function2(double x1, double y1, double x2, double length, int quadrant, double a, double b)
|
||
{
|
||
double y2 = 0;
|
||
double f = 0;
|
||
|
||
//<2F><><EFBFBD>и<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
// |
|
||
// 2 | 1
|
||
// |
|
||
//---------------
|
||
// |
|
||
// 3 | 4
|
||
// |
|
||
|
||
switch (quadrant) {
|
||
case 1:
|
||
y2 = b * Math.Sqrt(1 - Math.Pow((x2 - a) / a, 2));
|
||
break;
|
||
case 2:
|
||
y2 = b * Math.Sqrt(1 - Math.Pow((x2 + a) / a, 2));
|
||
break;
|
||
case 3:
|
||
y2 = -b * Math.Sqrt(1 - Math.Pow((x2 + a) / a, 2));
|
||
break;
|
||
case 4:
|
||
y2 = -b * Math.Sqrt(1 - Math.Pow((x2 - a) / a, 2));
|
||
break;
|
||
|
||
}
|
||
|
||
f = Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2)) - length;
|
||
return f;
|
||
}
|
||
|
||
private double FindY2(double x2, int quadrant, double a, double b)
|
||
{
|
||
double y2 = 0;
|
||
|
||
switch (quadrant) {
|
||
case 1:
|
||
y2 = b * Math.Sqrt(1 - Math.Pow((x2 - a) / a, 2));
|
||
break;
|
||
case 2:
|
||
y2 = b * Math.Sqrt(1 - Math.Pow((x2 + a) / a, 2));
|
||
break;
|
||
case 3:
|
||
y2 = -b * Math.Sqrt(1 - Math.Pow((x2 + a) / a, 2));
|
||
break;
|
||
case 4:
|
||
y2 = -b * Math.Sqrt(1 - Math.Pow((x2 - a) / a, 2));
|
||
break;
|
||
|
||
}
|
||
return y2;
|
||
}
|
||
|
||
public void LoadWobbelVectorForHead(out List<double> dTrans, out List<double> dLong, int KFactor)
|
||
{
|
||
CreateWobbelVectorPointList();
|
||
dTrans = new List<double>();
|
||
dLong = new List<double>();
|
||
|
||
for (int i = 0; i < m_headPoint.Count - 1; i++) {
|
||
dTrans.Add((m_headPoint[i + 1].X - m_headPoint[i].X) * KFactor / HeadPeriod);//dTrans = dx *kFactor /period
|
||
dLong.Add((m_headPoint[i + 1].Y - m_headPoint[i].Y) * KFactor / HeadPeriod);//dTrans = dx *kFactor /period
|
||
}
|
||
}
|
||
|
||
public void LoadWobbelVectorForBody(out List<double> dTrans, out List<double> dLong, int KFactor)
|
||
{
|
||
CreateWobbelVectorPointList();
|
||
dTrans = new List<double>();
|
||
dLong = new List<double>();
|
||
|
||
for (int i = 0; i < m_bodyPoint.Count - 1; i++) {
|
||
dTrans.Add((m_bodyPoint[i + 1].X - m_bodyPoint[i].X) * KFactor / BodyPeriod);//dTrans = dx *kFactor /period
|
||
dLong.Add((m_bodyPoint[i + 1].Y - m_bodyPoint[i].Y) * KFactor / BodyPeriod);//dTrans = dx *kFactor /period
|
||
}
|
||
}
|
||
|
||
public virtual IDrawObject Clone()
|
||
{
|
||
SnowMan l = new SnowMan();
|
||
l.Copy(this);
|
||
return l;
|
||
}
|
||
|
||
public RectangleF GetBoundingRect(ICanvas canvas)
|
||
{
|
||
float thWidth = ThresholdWidth(canvas, Width);
|
||
return ScreenUtils.GetRect(P1, P2, thWidth);
|
||
}
|
||
|
||
private void DrawSnowMan(ICanvas canvas, Pen pen)
|
||
{
|
||
double angle = 0;
|
||
if (DrawWay == eDrawWay.Left) {
|
||
angle = (-Angle + 90 + TiltingAngle) * Math.PI / 180;
|
||
} else {
|
||
angle = (-Angle + 90 - TiltingAngle) * Math.PI / 180;
|
||
}
|
||
|
||
//1.SnowMan <20><EFBFBD><D7B8><EFBFBD>
|
||
for (int i = 0; i < m_headPoint.Count - 1; i++) {
|
||
UnitPoint point1 = new UnitPoint(m_headPoint[i].X * Math.Cos(angle) + m_headPoint[i].Y * Math.Sin(angle) + P1.X, -m_headPoint[i].X * Math.Sin(angle) + m_headPoint[i].Y * Math.Cos(angle) + P1.Y);
|
||
UnitPoint point2 = new UnitPoint(m_headPoint[i + 1].X * Math.Cos(angle) + m_headPoint[i + 1].Y * Math.Sin(angle) + P1.X, -m_headPoint[i + 1].X * Math.Sin(angle) + m_headPoint[i + 1].Y * Math.Cos(angle) + P1.Y);
|
||
|
||
canvas.DrawLine(canvas, pen, point1, point2);
|
||
}
|
||
for (int i = 0; i < m_bodyPoint.Count - 1; i++) {
|
||
UnitPoint point1 = new UnitPoint(m_bodyPoint[i].X * Math.Cos(angle) + m_bodyPoint[i].Y * Math.Sin(angle) + P1.X, -m_bodyPoint[i].X * Math.Sin(angle) + m_bodyPoint[i].Y * Math.Cos(angle) + P1.Y);
|
||
UnitPoint point2 = new UnitPoint(m_bodyPoint[i + 1].X * Math.Cos(angle) + m_bodyPoint[i + 1].Y * Math.Sin(angle) + P1.X, -m_bodyPoint[i + 1].X * Math.Sin(angle) + m_bodyPoint[i + 1].Y * Math.Cos(angle) + P1.Y);
|
||
|
||
canvas.DrawLine(canvas, pen, point1, point2);
|
||
}
|
||
//2. Head ǥ<><C7A5><EFBFBD>ϱ<EFBFBD>
|
||
|
||
}
|
||
|
||
public virtual void Draw(ICanvas canvas, RectangleF unitrect)
|
||
{
|
||
Color color = Color;
|
||
|
||
color = WeldingParameterIDEditor.weldingColorList[(int)WeldingParameterID - 1];
|
||
Pen pen = canvas.CreatePen(color, Width);
|
||
canvas.DrawLine(canvas, pen, P1, P2);
|
||
|
||
|
||
if (canvas.CurrentObject == null) {
|
||
DrawSnowMan(canvas, pen);
|
||
DrawUtils.DrawArrowNode(canvas, P2, Angle, pen);
|
||
}
|
||
|
||
|
||
if (Highlighted) {
|
||
canvas.DrawLine(canvas, DrawUtils.SelectedPen, P1, P2);
|
||
}
|
||
|
||
if (Selected) {
|
||
canvas.DrawLine(canvas, DrawUtils.SelectedPen, P1, P2);
|
||
|
||
if (P1.IsEmpty == false) {
|
||
DrawUtils.DrawNode(canvas, P1);
|
||
}
|
||
|
||
if (P2.IsEmpty == false) {
|
||
DrawUtils.DrawTriangleNode(canvas, P2);
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
UnitPoint MidPoint(ICanvas canvas, UnitPoint p1, UnitPoint p2, UnitPoint hitpoint)
|
||
{
|
||
UnitPoint mid = HitUtil.LineMidpoint(p1, p2);
|
||
float thWidth = ThresholdWidth(canvas, Width);
|
||
if (HitUtil.CircleHitPoint(mid, thWidth, hitpoint))
|
||
return mid;
|
||
return UnitPoint.Empty;
|
||
}
|
||
|
||
public bool PointInObject(ICanvas canvas, UnitPoint point)
|
||
{
|
||
float thWidth = ThresholdWidth(canvas, Width);
|
||
return HitUtil.IsPointInLine(P1, P2, point, thWidth);
|
||
}
|
||
|
||
public bool ObjectInRectangle(ICanvas canvas, RectangleF rect, bool anyPoint)
|
||
{
|
||
RectangleF boundingrect = GetBoundingRect(canvas);
|
||
if (anyPoint)
|
||
return HitUtil.LineIntersectWithRect(P1, P2, rect);
|
||
return rect.Contains(boundingrect);
|
||
}
|
||
|
||
public virtual void OnMouseMove(ICanvas canvas, UnitPoint point)
|
||
{
|
||
P2 = point;
|
||
}
|
||
|
||
public virtual eDrawObjectMouseDown OnMouseDown(ICanvas canvas, UnitPoint point, ISnapPoint snappoint)
|
||
{
|
||
Selected = false;
|
||
if (snappoint is PerpendicularSnapPoint && snappoint.Owner is Line) {
|
||
Line src = snappoint.Owner as Line;
|
||
P2 = HitUtil.NearestPointOnLine(src.P1, src.P2, P1, true);
|
||
return eDrawObjectMouseDown.DoneRepeat;
|
||
}
|
||
if (snappoint is PerpendicularSnapPoint && snappoint.Owner is SnowMan) {
|
||
SnowMan src = snappoint.Owner as SnowMan;
|
||
P2 = HitUtil.NearestPointOnLine(src.P1, src.P2, P1, true);
|
||
return eDrawObjectMouseDown.DoneRepeat;
|
||
}
|
||
if (snappoint is PerpendicularSnapPoint && snappoint.Owner is Dot) {
|
||
Dot src = snappoint.Owner as Dot;
|
||
P2 = HitUtil.NearestPointOnCircle(src.P1, src.Width, P1, 0);
|
||
return eDrawObjectMouseDown.DoneRepeat;
|
||
}
|
||
if (snappoint is PerpendicularSnapPoint && snappoint.Owner is Spline) {
|
||
Spline src = snappoint.Owner as Spline;
|
||
P2 = HitUtil.NearestPointOnCircle(src.Center, src.Radius, P1, 0);
|
||
return eDrawObjectMouseDown.DoneRepeat;
|
||
}
|
||
if (snappoint is PerpendicularSnapPoint && snappoint.Owner is Arc) {
|
||
Arc src = snappoint.Owner as Arc;
|
||
P2 = HitUtil.NearestPointOnCircle(src.Center, src.Radius, P1, 0);
|
||
return eDrawObjectMouseDown.DoneRepeat;
|
||
}
|
||
if (System.Windows.Forms.Control.ModifierKeys == Keys.Control)
|
||
point = HitUtil.OrthoPointD(P1, point, 45);
|
||
P2 = point;
|
||
return eDrawObjectMouseDown.DoneRepeat;
|
||
}
|
||
|
||
public void OnMouseUp(ICanvas canvas, UnitPoint point, ISnapPoint snappoint)
|
||
{
|
||
}
|
||
|
||
public virtual void OnKeyDown(ICanvas canvas, KeyEventArgs e)
|
||
{
|
||
}
|
||
|
||
[Browsable(false)]
|
||
public UnitPoint RepeatStartingPoint {
|
||
get { return P2; }
|
||
}
|
||
|
||
public INodePoint NodePoint(ICanvas canvas, UnitPoint point)
|
||
{
|
||
float thWidth = ThresholdWidth(canvas, Width);
|
||
|
||
if (HitUtil.CircleHitPoint(P1, thWidth, point)) {
|
||
return new NodePointSnowMan(this, NodePointSnowMan.ePoint.P1);
|
||
}
|
||
|
||
if (HitUtil.CircleHitPoint(P2, thWidth, point)) {
|
||
return new NodePointSnowMan(this, NodePointSnowMan.ePoint.P2);
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public ISnapPoint SnapPoint(ICanvas canvas, UnitPoint point, List<IDrawObject> otherobjs, Type[] runningsnaptypes, Type usersnaptype)
|
||
{
|
||
float thWidth = ThresholdWidth(canvas, Width);
|
||
if (runningsnaptypes != null) {
|
||
foreach (Type snaptype in runningsnaptypes) {
|
||
if (snaptype == typeof(VertextSnapPoint)) {
|
||
if (HitUtil.CircleHitPoint(P1, thWidth, point))
|
||
return new VertextSnapPoint(canvas, this, P1);
|
||
if (HitUtil.CircleHitPoint(P2, thWidth, point))
|
||
return new VertextSnapPoint(canvas, this, P2);
|
||
}
|
||
if (snaptype == typeof(MidpointSnapPoint)) {
|
||
UnitPoint p = MidPoint(canvas, P1, P2, point);
|
||
if (p != UnitPoint.Empty)
|
||
return new MidpointSnapPoint(canvas, this, p);
|
||
}
|
||
if (snaptype == typeof(IntersectSnapPoint)) {
|
||
SnowMan otherline = Utils.FindObjectTypeInList(this, otherobjs, typeof(SnowMan)) as SnowMan;
|
||
if (otherline == null)
|
||
continue;
|
||
UnitPoint p = HitUtil.LinesIntersectPoint(P1, P2, otherline.P1, otherline.P2);
|
||
if (p != UnitPoint.Empty)
|
||
return new IntersectSnapPoint(canvas, this, p);
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
if (usersnaptype == typeof(MidpointSnapPoint))
|
||
return new MidpointSnapPoint(canvas, this, HitUtil.LineMidpoint(P1, P2));
|
||
if (usersnaptype == typeof(IntersectSnapPoint)) {
|
||
SnowMan otherline = Utils.FindObjectTypeInList(this, otherobjs, typeof(SnowMan)) as SnowMan;
|
||
if (otherline == null)
|
||
return null;
|
||
UnitPoint p = HitUtil.LinesIntersectPoint(P1, P2, otherline.P1, otherline.P2);
|
||
if (p != UnitPoint.Empty)
|
||
return new IntersectSnapPoint(canvas, this, p);
|
||
}
|
||
if (usersnaptype == typeof(VertextSnapPoint)) {
|
||
double d1 = HitUtil.Distance(point, P1);
|
||
double d2 = HitUtil.Distance(point, P2);
|
||
if (d1 <= d2)
|
||
return new VertextSnapPoint(canvas, this, P1);
|
||
return new VertextSnapPoint(canvas, this, P2);
|
||
}
|
||
if (usersnaptype == typeof(NearestSnapPoint)) {
|
||
UnitPoint p = HitUtil.NearestPointOnLine(P1, P2, point);
|
||
if (p != UnitPoint.Empty)
|
||
return new NearestSnapPoint(canvas, this, p);
|
||
}
|
||
if (usersnaptype == typeof(PerpendicularSnapPoint)) {
|
||
UnitPoint p = HitUtil.NearestPointOnLine(P1, P2, point);
|
||
if (p != UnitPoint.Empty)
|
||
return new PerpendicularSnapPoint(canvas, this, p);
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public void Move(UnitPoint offset)
|
||
{
|
||
m_p1.X += offset.X;
|
||
m_p1.Y += offset.Y;
|
||
m_p2.X += offset.X;
|
||
m_p2.Y += offset.Y;
|
||
}
|
||
|
||
public void Rotate(float angle, UnitPoint center)
|
||
{
|
||
// UnitPoint mid = Center;
|
||
P1 = HitUtil.RotatePoint(angle, P1, center);
|
||
P2 = HitUtil.RotatePoint(angle, P2, center);
|
||
}
|
||
|
||
public void MakeLength(float distance)
|
||
{
|
||
float slope = 0;
|
||
double gapX = 0;
|
||
double gapY = 0;
|
||
|
||
if (P1.X != P2.X) {
|
||
slope = (float)((P2.Y - P1.Y) / (P2.X - P1.X));
|
||
gapX = distance / (2 * Math.Sqrt(Math.Pow(slope, 2) + 1));
|
||
gapY = (distance * slope) / (2 * Math.Sqrt(Math.Pow(slope, 2) + 1));
|
||
} else {
|
||
gapY = distance * 0.5;
|
||
}
|
||
|
||
PointF pt1 = new PointF();
|
||
PointF pt2 = new PointF();
|
||
|
||
//<2F><><EFBFBD><EFBFBD>-<2D>ȿ<EFBFBD><C8BF><EFBFBD>-161017-<2D><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ȯ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
if (P1.X > P2.X) {
|
||
pt1.X = (float)(MiddlePoint.X + gapX);
|
||
pt2.X = (float)(MiddlePoint.X - gapX);
|
||
} else {
|
||
pt1.X = (float)(MiddlePoint.X - gapX);
|
||
pt2.X = (float)(MiddlePoint.X + gapX);
|
||
}
|
||
|
||
if (P1.Y > P2.Y) {
|
||
pt1.Y = (float)(MiddlePoint.Y + gapY);
|
||
pt2.Y = (float)(MiddlePoint.Y - gapY);
|
||
} else {
|
||
pt1.Y = (float)(MiddlePoint.Y - gapY);
|
||
pt2.Y = (float)(MiddlePoint.Y + gapY);
|
||
}
|
||
|
||
P1 = new UnitPoint(pt1.X, pt1.Y);
|
||
P2 = new UnitPoint(pt2.X, pt2.Y);
|
||
}
|
||
|
||
public virtual string GetInfoAsString()
|
||
{
|
||
return string.Format("{1:D3} {0}@{2},{3} - L={4:f4} <{5:f4}",
|
||
this.Type,
|
||
No + 1,
|
||
P1.PosAsString(),
|
||
P2.PosAsString(),
|
||
Distance,
|
||
Angle);
|
||
}
|
||
#endregion
|
||
|
||
#endregion
|
||
#region ISerialize
|
||
public void GetObjectData(XmlWriter wr)
|
||
{
|
||
wr.WriteStartElement("SnowMan");
|
||
XmlUtil.WriteProperties(this, wr);
|
||
wr.WriteEndElement();
|
||
}
|
||
|
||
public virtual string GetObjectData()
|
||
{
|
||
string jsonString = string.Empty;
|
||
var options = new JsonSerializerOptions { WriteIndented = true };
|
||
try {
|
||
jsonString += JsonSerializer.Serialize(this, options);
|
||
} catch {
|
||
|
||
}
|
||
return jsonString;
|
||
}
|
||
|
||
public void AfterSerializedIn()
|
||
{
|
||
}
|
||
#endregion
|
||
}
|
||
|
||
public class NodePointSnowMan : INodePoint
|
||
{
|
||
public enum ePoint
|
||
{
|
||
P1,
|
||
P2,
|
||
}
|
||
|
||
static bool m_angleLocked = false;
|
||
SnowMan m_owner;
|
||
SnowMan m_clone;
|
||
|
||
UnitPoint m_originalPoint;
|
||
public UnitPoint OriginalPoint {
|
||
get { lock (this) { return m_originalPoint; } }
|
||
set { lock (this) { m_originalPoint = value; } }
|
||
}
|
||
|
||
UnitPoint m_endPoint;
|
||
public UnitPoint EndPoint {
|
||
get { lock (this) { return m_endPoint; } }
|
||
set { lock (this) { m_endPoint = value; } }
|
||
}
|
||
|
||
ePoint m_pointId;
|
||
public ePoint PointId {
|
||
get { lock (this) { return m_pointId; } }
|
||
set { lock (this) { m_pointId = value; } }
|
||
}
|
||
|
||
public NodePointSnowMan(SnowMan owner, ePoint id)
|
||
{
|
||
m_owner = owner;
|
||
m_clone = m_owner.Clone() as SnowMan;
|
||
m_pointId = id;
|
||
m_originalPoint = GetPoint(m_pointId);
|
||
}
|
||
|
||
#region INodePoint Members
|
||
public IDrawObject GetClone()
|
||
{
|
||
return m_clone;
|
||
}
|
||
|
||
public IDrawObject GetOriginal()
|
||
{
|
||
return m_owner;
|
||
}
|
||
|
||
public void SetPosition(UnitPoint pos)
|
||
{
|
||
if (System.Windows.Forms.Control.ModifierKeys == Keys.Control)
|
||
pos = HitUtil.OrthoPointD(OtherPoint(m_pointId), pos, 45);
|
||
if (m_angleLocked || System.Windows.Forms.Control.ModifierKeys == (Keys)(Keys.Control | Keys.Shift))
|
||
pos = HitUtil.NearestPointOnLine(m_owner.P1, m_owner.P2, pos, true);
|
||
SetPoint(m_pointId, pos, m_clone);
|
||
}
|
||
|
||
public void Finish()
|
||
{
|
||
m_endPoint = GetPoint(m_pointId);
|
||
m_owner.P1 = m_clone.P1;
|
||
m_owner.P2 = m_clone.P2;
|
||
m_clone = null;
|
||
}
|
||
|
||
public void Cancel()
|
||
{
|
||
}
|
||
|
||
public void Undo()
|
||
{
|
||
SetPoint(m_pointId, m_originalPoint, m_owner);
|
||
}
|
||
|
||
public void Redo()
|
||
{
|
||
SetPoint(m_pointId, m_endPoint, m_owner);
|
||
}
|
||
|
||
public void OnKeyDown(ICanvas canvas, KeyEventArgs e)
|
||
{
|
||
if (e.KeyCode == Keys.L) {
|
||
m_angleLocked = !m_angleLocked;
|
||
e.Handled = true;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
protected UnitPoint GetPoint(ePoint pointid)
|
||
{
|
||
if (pointid == ePoint.P1)
|
||
return m_clone.P1;
|
||
if (pointid == ePoint.P2)
|
||
return m_clone.P2;
|
||
return m_owner.P1;
|
||
}
|
||
|
||
protected UnitPoint OtherPoint(ePoint currentpointid)
|
||
{
|
||
if (currentpointid == ePoint.P1)
|
||
return GetPoint(ePoint.P2);
|
||
return GetPoint(ePoint.P1);
|
||
}
|
||
|
||
protected void SetPoint(ePoint pointid, UnitPoint point, SnowMan snowMan)
|
||
{
|
||
if (pointid == ePoint.P1)
|
||
snowMan.P1 = point;
|
||
if (pointid == ePoint.P2)
|
||
snowMan.P2 = point;
|
||
}
|
||
}
|
||
|
||
public class SnowManEdit : SnowMan, IObjectEditInstance
|
||
{
|
||
protected PerpendicularSnapPoint m_perSnap;
|
||
protected TangentSnapPoint m_tanSnap;
|
||
protected bool m_tanReverse = false;
|
||
protected bool m_singleSnowManSegment = true;
|
||
|
||
public new string Type {
|
||
get {
|
||
if (m_singleSnowManSegment)
|
||
return "SnowMan";
|
||
return "SnowMans";
|
||
}
|
||
}
|
||
|
||
public SnowManEdit(bool singleSnowMan)
|
||
: base()
|
||
{
|
||
m_singleSnowManSegment = singleSnowMan;
|
||
}
|
||
|
||
public override void InitializeFromModel(UnitPoint point, DrawingLayer layer, ISnapPoint snap)
|
||
{
|
||
base.InitializeFromModel(point, layer, snap);
|
||
m_perSnap = snap as PerpendicularSnapPoint;
|
||
m_tanSnap = snap as TangentSnapPoint;
|
||
}
|
||
|
||
public override void OnMouseMove(ICanvas canvas, UnitPoint point)
|
||
{
|
||
if (m_perSnap != null) {
|
||
MouseMovePerpendicular(canvas, point);
|
||
return;
|
||
}
|
||
if (m_tanSnap != null) {
|
||
MouseMoveTangent(canvas, point);
|
||
return;
|
||
}
|
||
base.OnMouseMove(canvas, point);
|
||
}
|
||
|
||
public override eDrawObjectMouseDown OnMouseDown(ICanvas canvas, UnitPoint point, ISnapPoint snappoint)
|
||
{
|
||
if (m_tanSnap != null && System.Windows.Forms.Control.MouseButtons == MouseButtons.Right) {
|
||
ReverseTangent(canvas);
|
||
return eDrawObjectMouseDown.Continue;
|
||
}
|
||
|
||
if (m_perSnap != null || m_tanSnap != null) {
|
||
if (snappoint != null)
|
||
point = snappoint.SnapPoint;
|
||
OnMouseMove(canvas, point);
|
||
if (m_singleSnowManSegment)
|
||
return eDrawObjectMouseDown.Done;
|
||
return eDrawObjectMouseDown.DoneRepeat;
|
||
}
|
||
eDrawObjectMouseDown result = base.OnMouseDown(canvas, point, snappoint);
|
||
if (m_singleSnowManSegment)
|
||
return eDrawObjectMouseDown.Done;
|
||
return eDrawObjectMouseDown.DoneRepeat;
|
||
}
|
||
|
||
public override void OnKeyDown(ICanvas canvas, KeyEventArgs e)
|
||
{
|
||
if (e.KeyCode == Keys.R && m_tanSnap != null) {
|
||
ReverseTangent(canvas);
|
||
e.Handled = true;
|
||
}
|
||
}
|
||
|
||
protected virtual void MouseMovePerpendicular(ICanvas canvas, UnitPoint point)
|
||
{
|
||
if (m_perSnap.Owner is Line) {
|
||
Line src = m_perSnap.Owner as Line;
|
||
P1 = HitUtil.NearestPointOnLine(src.P1, src.P2, point, true);
|
||
P2 = point;
|
||
}
|
||
if (m_perSnap.Owner is SnowMan) {
|
||
SnowMan src = m_perSnap.Owner as SnowMan;
|
||
P1 = HitUtil.NearestPointOnLine(src.P1, src.P2, point, true);
|
||
P2 = point;
|
||
}
|
||
if (m_perSnap.Owner is Dot) {
|
||
Dot src = m_perSnap.Owner as Dot;
|
||
P1 = HitUtil.NearestPointOnCircle(src.P1, src.Width, point, 0);
|
||
P2 = point;
|
||
}
|
||
if (m_perSnap.Owner is Spline) {
|
||
IArc src = m_perSnap.Owner as IArc;
|
||
P1 = HitUtil.NearestPointOnCircle(src.Center, src.Radius, point, 0);
|
||
P2 = point;
|
||
}
|
||
if (m_perSnap.Owner is IArc) {
|
||
IArc src = m_perSnap.Owner as IArc;
|
||
P1 = HitUtil.NearestPointOnCircle(Center, src.Radius, point, 0);
|
||
P2 = point;
|
||
}
|
||
}
|
||
|
||
protected virtual void MouseMoveTangent(ICanvas canvas, UnitPoint point)
|
||
{
|
||
if (m_tanSnap.Owner is IArc) {
|
||
IArc src = m_tanSnap.Owner as IArc;
|
||
P1 = HitUtil.TangentPointOnCircle(Center, src.Radius, point, m_tanReverse);
|
||
P2 = point;
|
||
if (P1 == UnitPoint.Empty)
|
||
P2 = P1 = Center;
|
||
}
|
||
}
|
||
|
||
protected virtual void ReverseTangent(ICanvas canvas)
|
||
{
|
||
m_tanReverse = !m_tanReverse;
|
||
MouseMoveTangent(canvas, P2);
|
||
canvas.Invalidate(false);
|
||
}
|
||
|
||
public void Copy(SnowManEdit acopy)
|
||
{
|
||
base.Copy(acopy);
|
||
m_perSnap = acopy.m_perSnap;
|
||
m_tanSnap = acopy.m_tanSnap;
|
||
m_tanReverse = acopy.m_tanReverse;
|
||
m_singleSnowManSegment = acopy.m_singleSnowManSegment;
|
||
}
|
||
|
||
public override IDrawObject Clone()
|
||
{
|
||
SnowManEdit l = new SnowManEdit(false);
|
||
l.Copy(this);
|
||
return l;
|
||
}
|
||
|
||
#region IObjectEditInstance
|
||
public IDrawObject GetDrawObject()
|
||
{
|
||
|
||
return new SnowMan(P1, P2, Width, Color);
|
||
}
|
||
#endregion
|
||
}
|
||
}
|