diff --git a/AGVLogic/AGVMapEditor/Forms/MainForm.Designer.cs b/AGVLogic/AGVMapEditor/Forms/MainForm.Designer.cs
index 6da0e28..323576b 100644
--- a/AGVLogic/AGVMapEditor/Forms/MainForm.Designer.cs
+++ b/AGVLogic/AGVMapEditor/Forms/MainForm.Designer.cs
@@ -40,6 +40,16 @@ namespace AGVMapEditor.Forms
this.lstNodeConnection = new System.Windows.Forms.ListBox();
this.toolStrip1 = new System.Windows.Forms.ToolStrip();
this.btNodeRemove = new System.Windows.Forms.ToolStripButton();
+ this.tabPage2 = new System.Windows.Forms.TabPage();
+ this.lstMagnetDirection = new System.Windows.Forms.ListBox();
+ this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
+ this.button1 = new System.Windows.Forms.Button();
+ this.button2 = new System.Windows.Forms.Button();
+ this.button3 = new System.Windows.Forms.Button();
+ this.toolStrip4 = new System.Windows.Forms.ToolStrip();
+ this.btDirDelete = new System.Windows.Forms.ToolStripButton();
+ this.btMakeDirdata = new System.Windows.Forms.ToolStripButton();
+ this.toolStripButton2 = new System.Windows.Forms.ToolStripButton();
this._propertyGrid = new System.Windows.Forms.PropertyGrid();
this.panel1 = new System.Windows.Forms.Panel();
this.toolStrip3 = new System.Windows.Forms.ToolStrip();
@@ -67,16 +77,7 @@ namespace AGVMapEditor.Forms
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.toolStripButton1 = new System.Windows.Forms.ToolStripDropDownButton();
this.allTurnLeftRightCrossOnToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.tabPage2 = new System.Windows.Forms.TabPage();
- this.lstMagnetDirection = new System.Windows.Forms.ListBox();
- this.toolStrip4 = new System.Windows.Forms.ToolStrip();
- this.btDirDelete = new System.Windows.Forms.ToolStripButton();
- this.btMakeDirdata = new System.Windows.Forms.ToolStripButton();
- this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
- this.button1 = new System.Windows.Forms.Button();
- this.button2 = new System.Windows.Forms.Button();
- this.button3 = new System.Windows.Forms.Button();
- this.toolStripButton2 = new System.Windows.Forms.ToolStripButton();
+ this.btAddMagnet = new System.Windows.Forms.ToolStripButton();
this.statusStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
@@ -86,11 +87,11 @@ namespace AGVMapEditor.Forms
this.tabPageNodes.SuspendLayout();
this.tabPage1.SuspendLayout();
this.toolStrip1.SuspendLayout();
+ this.tabPage2.SuspendLayout();
+ this.tableLayoutPanel1.SuspendLayout();
+ this.toolStrip4.SuspendLayout();
this.toolStrip3.SuspendLayout();
this.toolStrip2.SuspendLayout();
- this.tabPage2.SuspendLayout();
- this.toolStrip4.SuspendLayout();
- this.tableLayoutPanel1.SuspendLayout();
this.SuspendLayout();
//
// statusStrip1
@@ -215,6 +216,120 @@ namespace AGVMapEditor.Forms
this.btNodeRemove.Text = "Remove";
this.btNodeRemove.Click += new System.EventHandler(this.btNodeRemove_Click);
//
+ // tabPage2
+ //
+ this.tabPage2.Controls.Add(this.lstMagnetDirection);
+ this.tabPage2.Controls.Add(this.tableLayoutPanel1);
+ this.tabPage2.Controls.Add(this.toolStrip4);
+ this.tabPage2.Location = new System.Drawing.Point(4, 22);
+ this.tabPage2.Name = "tabPage2";
+ this.tabPage2.Size = new System.Drawing.Size(292, 309);
+ this.tabPage2.TabIndex = 2;
+ this.tabPage2.Text = "방향 관리";
+ this.tabPage2.UseVisualStyleBackColor = true;
+ //
+ // lstMagnetDirection
+ //
+ this.lstMagnetDirection.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.lstMagnetDirection.FormattingEnabled = true;
+ this.lstMagnetDirection.ItemHeight = 12;
+ this.lstMagnetDirection.Location = new System.Drawing.Point(0, 25);
+ this.lstMagnetDirection.Name = "lstMagnetDirection";
+ this.lstMagnetDirection.Size = new System.Drawing.Size(292, 246);
+ this.lstMagnetDirection.TabIndex = 3;
+ //
+ // tableLayoutPanel1
+ //
+ this.tableLayoutPanel1.ColumnCount = 3;
+ this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
+ this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
+ this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
+ this.tableLayoutPanel1.Controls.Add(this.button1, 0, 0);
+ this.tableLayoutPanel1.Controls.Add(this.button2, 1, 0);
+ this.tableLayoutPanel1.Controls.Add(this.button3, 2, 0);
+ this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 271);
+ this.tableLayoutPanel1.Name = "tableLayoutPanel1";
+ this.tableLayoutPanel1.RowCount = 1;
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 38F));
+ this.tableLayoutPanel1.Size = new System.Drawing.Size(292, 38);
+ this.tableLayoutPanel1.TabIndex = 6;
+ //
+ // button1
+ //
+ this.button1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.button1.Location = new System.Drawing.Point(3, 3);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(91, 32);
+ this.button1.TabIndex = 0;
+ this.button1.Text = "Left";
+ this.button1.UseVisualStyleBackColor = true;
+ this.button1.Click += new System.EventHandler(this.button1_Click);
+ //
+ // button2
+ //
+ this.button2.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.button2.Location = new System.Drawing.Point(100, 3);
+ this.button2.Name = "button2";
+ this.button2.Size = new System.Drawing.Size(91, 32);
+ this.button2.TabIndex = 0;
+ this.button2.Text = "Straight";
+ this.button2.UseVisualStyleBackColor = true;
+ this.button2.Click += new System.EventHandler(this.button2_Click);
+ //
+ // button3
+ //
+ this.button3.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.button3.Location = new System.Drawing.Point(197, 3);
+ this.button3.Name = "button3";
+ this.button3.Size = new System.Drawing.Size(92, 32);
+ this.button3.TabIndex = 0;
+ this.button3.Text = "Right";
+ this.button3.UseVisualStyleBackColor = true;
+ this.button3.Click += new System.EventHandler(this.button3_Click);
+ //
+ // toolStrip4
+ //
+ this.toolStrip4.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.btDirDelete,
+ this.btMakeDirdata,
+ this.toolStripButton2});
+ this.toolStrip4.Location = new System.Drawing.Point(0, 0);
+ this.toolStrip4.Name = "toolStrip4";
+ this.toolStrip4.Size = new System.Drawing.Size(292, 25);
+ this.toolStrip4.TabIndex = 5;
+ this.toolStrip4.Text = "toolStrip4";
+ //
+ // btDirDelete
+ //
+ this.btDirDelete.Image = ((System.Drawing.Image)(resources.GetObject("btDirDelete.Image")));
+ this.btDirDelete.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.btDirDelete.Name = "btDirDelete";
+ this.btDirDelete.Size = new System.Drawing.Size(61, 22);
+ this.btDirDelete.Text = "Delete";
+ this.btDirDelete.Click += new System.EventHandler(this.btDirDelete_Click);
+ //
+ // btMakeDirdata
+ //
+ this.btMakeDirdata.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
+ this.btMakeDirdata.Image = ((System.Drawing.Image)(resources.GetObject("btMakeDirdata.Image")));
+ this.btMakeDirdata.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.btMakeDirdata.Name = "btMakeDirdata";
+ this.btMakeDirdata.Size = new System.Drawing.Size(69, 22);
+ this.btMakeDirdata.Text = "Remake";
+ this.btMakeDirdata.Click += new System.EventHandler(this.toolStripButton3_Click);
+ //
+ // toolStripButton2
+ //
+ this.toolStripButton2.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
+ this.toolStripButton2.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton2.Image")));
+ this.toolStripButton2.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.toolStripButton2.Name = "toolStripButton2";
+ this.toolStripButton2.Size = new System.Drawing.Size(54, 22);
+ this.toolStripButton2.Text = "Clear";
+ this.toolStripButton2.Click += new System.EventHandler(this.toolStripButton2_Click);
+ //
// _propertyGrid
//
this._propertyGrid.Dock = System.Windows.Forms.DockStyle.Bottom;
@@ -244,7 +359,8 @@ namespace AGVMapEditor.Forms
this.btnDeleteConnection,
this.toolStripSeparator1,
this.btnToggleGrid,
- this.btnFitMap});
+ this.btnFitMap,
+ this.btAddMagnet});
this.toolStrip3.Location = new System.Drawing.Point(0, 0);
this.toolStrip3.Name = "toolStrip3";
this.toolStrip3.Size = new System.Drawing.Size(896, 25);
@@ -458,119 +574,14 @@ namespace AGVMapEditor.Forms
this.allTurnLeftRightCrossOnToolStripMenuItem.Text = "All TurnLeft/Right/Cross On";
this.allTurnLeftRightCrossOnToolStripMenuItem.Click += new System.EventHandler(this.allTurnLeftRightCrossOnToolStripMenuItem_Click);
//
- // tabPage2
+ // btAddMagnet
//
- this.tabPage2.Controls.Add(this.lstMagnetDirection);
- this.tabPage2.Controls.Add(this.tableLayoutPanel1);
- this.tabPage2.Controls.Add(this.toolStrip4);
- this.tabPage2.Location = new System.Drawing.Point(4, 22);
- this.tabPage2.Name = "tabPage2";
- this.tabPage2.Size = new System.Drawing.Size(292, 309);
- this.tabPage2.TabIndex = 2;
- this.tabPage2.Text = "방향 관리";
- this.tabPage2.UseVisualStyleBackColor = true;
- //
- // lstMagnetDirection
- //
- this.lstMagnetDirection.Dock = System.Windows.Forms.DockStyle.Fill;
- this.lstMagnetDirection.FormattingEnabled = true;
- this.lstMagnetDirection.ItemHeight = 12;
- this.lstMagnetDirection.Location = new System.Drawing.Point(0, 25);
- this.lstMagnetDirection.Name = "lstMagnetDirection";
- this.lstMagnetDirection.Size = new System.Drawing.Size(292, 246);
- this.lstMagnetDirection.TabIndex = 3;
- //
- // toolStrip4
- //
- this.toolStrip4.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
- this.btDirDelete,
- this.btMakeDirdata,
- this.toolStripButton2});
- this.toolStrip4.Location = new System.Drawing.Point(0, 0);
- this.toolStrip4.Name = "toolStrip4";
- this.toolStrip4.Size = new System.Drawing.Size(292, 25);
- this.toolStrip4.TabIndex = 5;
- this.toolStrip4.Text = "toolStrip4";
- //
- // btDirDelete
- //
- this.btDirDelete.Image = ((System.Drawing.Image)(resources.GetObject("btDirDelete.Image")));
- this.btDirDelete.ImageTransparentColor = System.Drawing.Color.Magenta;
- this.btDirDelete.Name = "btDirDelete";
- this.btDirDelete.Size = new System.Drawing.Size(61, 22);
- this.btDirDelete.Text = "Delete";
- this.btDirDelete.Click += new System.EventHandler(this.btDirDelete_Click);
- //
- // btMakeDirdata
- //
- this.btMakeDirdata.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
- this.btMakeDirdata.Image = ((System.Drawing.Image)(resources.GetObject("btMakeDirdata.Image")));
- this.btMakeDirdata.ImageTransparentColor = System.Drawing.Color.Magenta;
- this.btMakeDirdata.Name = "btMakeDirdata";
- this.btMakeDirdata.Size = new System.Drawing.Size(69, 22);
- this.btMakeDirdata.Text = "Remake";
- this.btMakeDirdata.Click += new System.EventHandler(this.toolStripButton3_Click);
- //
- // tableLayoutPanel1
- //
- this.tableLayoutPanel1.ColumnCount = 3;
- this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
- this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
- this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
- this.tableLayoutPanel1.Controls.Add(this.button1, 0, 0);
- this.tableLayoutPanel1.Controls.Add(this.button2, 1, 0);
- this.tableLayoutPanel1.Controls.Add(this.button3, 2, 0);
- this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Bottom;
- this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 271);
- this.tableLayoutPanel1.Name = "tableLayoutPanel1";
- this.tableLayoutPanel1.RowCount = 1;
- this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
- this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
- this.tableLayoutPanel1.Size = new System.Drawing.Size(292, 38);
- this.tableLayoutPanel1.TabIndex = 6;
- //
- // button1
- //
- this.button1.Dock = System.Windows.Forms.DockStyle.Fill;
- this.button1.Location = new System.Drawing.Point(3, 3);
- this.button1.Name = "button1";
- this.button1.Size = new System.Drawing.Size(91, 32);
- this.button1.TabIndex = 0;
- this.button1.Text = "Left";
- this.button1.UseVisualStyleBackColor = true;
- this.button1.Click += new System.EventHandler(this.button1_Click);
- //
- // button2
- //
- this.button2.Dock = System.Windows.Forms.DockStyle.Fill;
- this.button2.Location = new System.Drawing.Point(100, 3);
- this.button2.Name = "button2";
- this.button2.Size = new System.Drawing.Size(91, 32);
- this.button2.TabIndex = 0;
- this.button2.Text = "Straight";
- this.button2.UseVisualStyleBackColor = true;
- this.button2.Click += new System.EventHandler(this.button2_Click);
- //
- // button3
- //
- this.button3.Dock = System.Windows.Forms.DockStyle.Fill;
- this.button3.Location = new System.Drawing.Point(197, 3);
- this.button3.Name = "button3";
- this.button3.Size = new System.Drawing.Size(92, 32);
- this.button3.TabIndex = 0;
- this.button3.Text = "Right";
- this.button3.UseVisualStyleBackColor = true;
- this.button3.Click += new System.EventHandler(this.button3_Click);
- //
- // toolStripButton2
- //
- this.toolStripButton2.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
- this.toolStripButton2.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton2.Image")));
- this.toolStripButton2.ImageTransparentColor = System.Drawing.Color.Magenta;
- this.toolStripButton2.Name = "toolStripButton2";
- this.toolStripButton2.Size = new System.Drawing.Size(54, 22);
- this.toolStripButton2.Text = "Clear";
- this.toolStripButton2.Click += new System.EventHandler(this.toolStripButton2_Click);
+ this.btAddMagnet.Image = ((System.Drawing.Image)(resources.GetObject("btAddMagnet.Image")));
+ this.btAddMagnet.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.btAddMagnet.Name = "btAddMagnet";
+ this.btAddMagnet.Size = new System.Drawing.Size(87, 22);
+ this.btAddMagnet.Text = "마그넷추가";
+ this.btAddMagnet.Click += new System.EventHandler(this.btAddMagnet_Click);
//
// MainForm
//
@@ -599,15 +610,15 @@ namespace AGVMapEditor.Forms
this.tabPage1.PerformLayout();
this.toolStrip1.ResumeLayout(false);
this.toolStrip1.PerformLayout();
+ this.tabPage2.ResumeLayout(false);
+ this.tabPage2.PerformLayout();
+ this.tableLayoutPanel1.ResumeLayout(false);
+ this.toolStrip4.ResumeLayout(false);
+ this.toolStrip4.PerformLayout();
this.toolStrip3.ResumeLayout(false);
this.toolStrip3.PerformLayout();
this.toolStrip2.ResumeLayout(false);
this.toolStrip2.PerformLayout();
- this.tabPage2.ResumeLayout(false);
- this.tabPage2.PerformLayout();
- this.toolStrip4.ResumeLayout(false);
- this.toolStrip4.PerformLayout();
- this.tableLayoutPanel1.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
@@ -663,5 +674,6 @@ namespace AGVMapEditor.Forms
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.ToolStripButton toolStripButton2;
+ private System.Windows.Forms.ToolStripButton btAddMagnet;
}
}
\ No newline at end of file
diff --git a/AGVLogic/AGVMapEditor/Forms/MainForm.cs b/AGVLogic/AGVMapEditor/Forms/MainForm.cs
index f4ad0ad..810bb56 100644
--- a/AGVLogic/AGVMapEditor/Forms/MainForm.cs
+++ b/AGVLogic/AGVMapEditor/Forms/MainForm.cs
@@ -774,7 +774,7 @@ namespace AGVMapEditor.Forms
private void RefreshNodeList()
{
listBoxNodes.DataSource = null;
- listBoxNodes.DataSource = this._mapCanvas.Nodes;
+ listBoxNodes.DataSource = this._mapCanvas.Items;
listBoxNodes.DisplayMember = "DisplayText";
listBoxNodes.ValueMember = "Id";
@@ -790,7 +790,7 @@ namespace AGVMapEditor.Forms
private void ListBoxNodes_SelectedIndexChanged(object sender, EventArgs e)
{
- if (listBoxNodes.SelectedItem is MapNode selectedNode)
+ if (listBoxNodes.SelectedItem is NodeBase selectedNode)
{
_selectedNode = selectedNode;
UpdateNodeProperties();
@@ -1673,5 +1673,52 @@ namespace AGVMapEditor.Forms
// 현재 선택된 노드의 속성창 및 리스트 갱신
UpdateNodeProperties();
}
+
+ private void btAddMagnet_Click(object sender, EventArgs e)
+ {
+ // 마그넷 추가
+ var result = MessageBox.Show("곡선 마그넷(Bezier)을 추가하시겠습니까?\n(예: 베지어 곡선, 아니오: 직선, 취소: 중단)",
+ "마그넷 타입 선택", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
+
+ if (result == DialogResult.Cancel) return;
+
+ bool isBezier = (result == DialogResult.Yes);
+
+ // 화면 중앙 좌표 계산 (World Coordinate)
+ float zoom = _mapCanvas.ZoomFactor;
+ PointF pan = _mapCanvas.PanOffset;
+
+ float worldCX = (_mapCanvas.Width / 2f) / zoom - pan.X;
+ float worldCY = (_mapCanvas.Height / 2f) / zoom - pan.Y;
+
+ // 고유 ID 생성
+ string id = _mapCanvas.GenerateUniqueNodeId();
+
+ var magnet = new MapMagnet { Id = id };
+
+ // 점 생성 시 정규화(Snap) 처리
+ int cx = (int)worldCX;
+ int cy = (int)worldCY;
+
+ magnet.StartPoint = new Point(cx - 50, cy);
+ magnet.EndPoint = new Point(cx + 50, cy);
+
+ if (isBezier)
+ {
+ magnet.ControlPoint = new MapMagnet.MagnetPoint { X = cx, Y = cy - 50 };
+ }
+
+ // 캔버스에 추가
+ _mapCanvas.Magnets.Add(magnet);
+ _hasChanges = true;
+
+ UpdateTitle();
+ RefreshMapCanvas();
+ RefreshNodeList();
+
+ // 추가된 마그넷 선택
+ //_mapCanvas.SelectedNode = magnet;
+ UpdateNodeProperties();
+ }
}
}
\ No newline at end of file
diff --git a/AGVLogic/AGVMapEditor/Forms/MainForm.resx b/AGVLogic/AGVMapEditor/Forms/MainForm.resx
index 8cc428a..1bc0a34 100644
--- a/AGVLogic/AGVMapEditor/Forms/MainForm.resx
+++ b/AGVLogic/AGVMapEditor/Forms/MainForm.resx
@@ -194,14 +194,14 @@
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHrSURBVDhPldBLaBNBHMfx/0kUVBBJ0lxWPIhihBJKyAqS
- pHkQIS+9hXg3RhQviicrITnmJqFnQQ8RqiamRqkhj6VCQtuIQaVQc5di3d3s61Dy0w002KnU9nP67+x8
+ pHkQIS+9hXg3RhQviicrITnmJqFnQQ8RqiamRqkhj6VCQtuIQaVQc7dg3d3s61Dy0w002KnU9nP67+x8
h2GIDmD0kT+mLk/fZNf3pQkznCrM3DFnZflSRG05euast7izcpM72GGqMP1ZFRw1tXm+qq9dg9LiHgwb
dnFYP51i9/6T0r4wp39Kwfh2F8bGI2irEYjvTmo/Gpbj7N4JpXNxShUcdbV1DvpaHMb3HNrP4uiVb2Cj
cQtadxbSh6OQ3tM82+6iNLk5rXcd7ecJGIaB0WiE1dcp6F9v41eNvmxV6QzbTMjtKYtct9Wi0Si63S50
XUe/30fjaQTG+n1IVRpKb4lnuzFtyc4Nl06VE4kE0uk0CoUCSqUSqvOzMNYfYnORtqVFWhEr9JhtJ+Lx
+DjmeR5+vx+xWAzqSgRy3Q65dgJbFeLYZmIndrvd8Pl8sFqt5pWfbL6hbalCl6Uy9cSXlGG7sWQyiXw+
P469Xi8sFgvMdblCV6RXVDNnvKAjPxfoKttSOBxGLpfbE+8QFyj09/cugUAA2WwWLpcLHo9nT7yvTCaD
- wWAAp9OJUCh0uNhkHtDpdFAsFscPxv7/r2AweM+8ts1mO3z8x29KrQsZMgRtMAAAAABJRU5ErkJggg==
+ wWAAp9OJUCh0uNhkHtDpdFAsFscPxv7/r2AweM+8ts1mO3z8x29G9wsX9Ki7DgAAAABJRU5ErkJggg==
@@ -222,75 +222,75 @@
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
- YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHJSURBVDhPnZJfa9pgFMb7JXa7sW9RkH2y3awro5dbS7Et
- u2vHRsRcBEw0QkTinyhB8e9MonOZ6NRZaME12YzyjPPKm+LcKtsDIbznPc/vOSRnr91uo9VqodFooF6v
- o1aroVqtolKp0PvR3i41m02sVqutZzgcMoiu6w9DKJkMg8GAJbuuG0KoZprmwxAamZopjc7lcrkyn88R
- BAGrE9AwjL9DKJU35vP5n4VCYeD7Pr59vUNBnbK7fr+PXC73Zwgl85GXyyXIfD31cXbo4Pi5jXxqDen1
- eshms1AUZRNimqY3m81Y02KxYMnRlw4uX/fx/tTF+WE3hDiOA03TNiGlUumZYRjedLpusuo3LPnq+DOE
- 8y9bENu2oarqJqRYLEY0TfMmkwlr6rZuET2w8e7kHhI9cKAr6/tOpwNZliEIwj1E1/VIOp32xuPxFuRD
- 1MXbox4ujj4iCJZsimQyiXg8/iQEkDKZTCSVSnmj0SiEnL6wcPGqi6uTLr7P/dAsCMLTDTOXqqoMQpvI
- PlzzBpdvPuGHH+w2c8myHEkkEh5tIv/FZFYUZbeZS5KkfUmSPFowy7L+zcwliuK+KIref5m5CBKLxR7/
- Xuf6BYuvFpozmyYBAAAAAElFTkSuQmCC
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHHSURBVDhPnZJva9pQFMb7JfZ2Y9+iIPtke7OujL7sWopr
+ 2bt2bETMi4CJXlCROI0SFP/OJDqXiladgw7cks0ozzhXbopzq2wPhHDPOc/vOSR3r91uo9VqodFooF6v
+ o1aroVqtolKp0PvB3i41m02sVqutZzgccoiu6/dDKJkMg8GAJ7uuG0KoZprm/RBamYYpjc7lcrkyn88R
+ BAGvE9AwjL9DKFUM5vP5n4VCYeD7Pj7ffEeBTXmv3+9T788QShYrL5dLkPnL1MerQwcnT228T60hvV4P
+ uVwOmqZtQkzT9GazGR9aLBY8OfrcweVxH2/PXJwfdkOI4zjIZDKbkFKp9MQwDG86XQ9Z9VuefHXyCdL5
+ 9RbEtm0wxjYhxWIxkk6nvclkwoe6ra+IHth4c3oHiR440LV1v9PpQFVVSJJ0B9F1PcIY88bj8RbkXdTF
+ 66MeLo4+IAiWfItkMol4PP4oBJCy2WwklUp5o9EohJw9s3Dxoour0y6+zf3QLEnS4w2zEGOMQ+gm8g/X
+ vMXly4/44Qe7zUKqqkYSiYRHN1H8YjJrmrbbLKQoyr6iKB5dMMuy/s0sJMvyvizL3n+ZhQgSi8Ue/l4X
+ +gV3kBaRV83skgAAAABJRU5ErkJggg==
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
- YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAG7SURBVDhPnZLditpQFIXnJXrb0rcYkD5YL4pMYS7bGUrp
- O0TMRUp+hWRs/IkSFDUGfxARR6viRRmkJ+jJYZVzhpPB2o60C0LI3nt9a0P2RRzH6Pf76PV66Ha76HQ6
- aLfbaLVa/P3i4pyiKAJj7ORZLBYC4vv+8xCezA3z+Vwkz2azDMJrYRg+D+Er82Gexr+bzWZrt9uBUirq
- HBgEwd8hPFUOVqvVfa1WmydJAvrjO2hsi950OkWlUvkzhCfLldM0BTezhw1S6wrp17egsSV6k8kE5XIZ
- pmkeQ8IwJNvtVgwdDgeRnJp5MO8D2LdPYNZVBhmPx3Bd9xjSaDTeBEFANpvNI+S+I5LZ3Q1Y5csJZDQa
- wXGcY0i9Xs+5rkvW6/UjZBmBGnmwu9sniJkHjXTRHwwGMAwDiqI8QXzfz5VKJbJarU4h/mcw5xo/jWuw
- lIotLMtCsVh8lQG4PM/L2bZNlstlBjno78Ds90jcG+zJLjMrivL6yCzlOI6A8EsUkEUP1PsItk/Om6UM
- w8jpuk74JcpfzM2maZ43S2madqlpGuEHNhwO/80sparqpaqq5L/MUhxSKBRe/l6X+gWA2x2MFEPZrwAA
- AABJRU5ErkJggg==
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAG4SURBVDhPnZLditpQFIXnJXrb0rcYkD5YL4pMYS7bKaX0
+ HSLmIiV/BzRjIxolKGoM/iAijlbFizLIJOjJYZV9hmSwtiPtghCy917f2pB9EYYh+v0+er0eut0uOp0O
+ 2u02Wq0WvV9cnFMQBBBCnDyLxUJCXNd9HkLJZJjP5zJ5NptlEKr5vv88hFamYUqj72az2drtduCcyzoB
+ Pc/7O4RS08Fqtbqv1WrzOI7Bf/4AD23Zm06n1PszhJLTlZMkAZnF/QaJdYXk21vw0JK9yWSCSqUC0zSP
+ Ib7vR9vtVg4dDgeZnJh5COcDxPfPENZVBhmPxyiXy8eQRqPxxvO8aLPZPELuOjJZ3N5AVL+eQEajERhj
+ x5B6vZ4rlUrRer1+hCwDcCMPcfvpCWLmwQNd9geDAQzDgKIoTxDXdXOMsWi1Wp1C3C8Q7BoPxjVEwuUW
+ lmWhWCy+ygAkx3Fytm1Hy+Uygxz0dxD2e8TlG+yjXWZWFOX1kTkVY0xC6BIlZNEDdz5C7OPz5lSGYeR0
+ XY/oEtNfTGbTNM+bU2madqlpWkQHNhwO/82cSlXVS1VVo/8ypyJIoVB4+Xs91S9svB2DRfl8BwAAAABJ
+ RU5ErkJggg==
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
- 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
+ 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
- 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
+ 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
- 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
- ns8f9tyLJQW2uh8AAAAASUVORK5CYII=
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAL3SURBVDhPhdLfV9N1HMdx/oPuO93U6XTj6dRN3XasLC1P
+ lmlRHrfT4Vgno+PppA1HJGL6FRbjK4PD2IBvc6m0qSTDgeGmDgknfmEwQisMERZwYO67fbd95BA+O9up
+ pZx+vM55X33en8fnnM/7XaT4hmoVrzone1XN6vr/kj2q5jyt1hX9lZbOq/Mzsdg9PZ0mnRH/WYu6YD6R
+ ounEQKIA5F5O6Wkau6ap7YpQefZbXNdseEa+5HikioaQhQ/bHHza2oepdZyFlED2DmsFoM6lajm96ew0
+ UncPrkEb7aO7cQ5+QNOVEuzhnVh6D7Cz+Rhm5Trz2j8AqYyguXuGSr+bE5Eq7OEdHPlhO5bQO0iXirGG
+ PsFY/xUVR39iTssie4ceBLSMwNkTY5/PxddqBXK/AeniW+wPbuaL85uRAqUY5GqUdjc3jhXzy5mDRFpf
+ ItK4xpAHEmlB67nfkHx+bKHD1PWXUBl8E/P3m9gXKObz78poPLqH2aAJbbQL9BiJ0ZOEatbP5YE7ukDp
+ ncXmH6HMoyB17qImsAOp9z3KvR9hbStlYaySpelOZi9ayEZP8/utywzb3xdFudnGUwJXYC6P1PsifFZl
+ 4JD1RSTLWlrq1xMfq2Ale5nszVLiVz/muruEiOPtxbDt9SfywGJSYPa8hql9I7uPv4Kj/BmiyhbGvlnH
+ neheVsQAmQkj4vY2UuNmRhs23huuW/d0/hNrXde0eFIQmrhQqP5oB31ndjE7aPrzsgEx9S7JsXJuNr+K
+ opzSC1Ow5oHsA0DwQjXj5/awkg0hJku4e3s7WnQvP9tfZmZqEtlz3xgbvOpUPJEkqQuS6bsMB9386Dcz
+ 0i0zE95KZnIb8UgZEy1vsBj7lYX8Kl/5e5WdHWqN4+RQX245crKn+gVI3eKGYwtB88P02zcQOPTcSpvi
+ 03Pn8qkhzdmhygVgdQ4YH19eGmhgKXyE8MG1uI2P6D2mNU+t7vvXbHr2ISEZH132H96w3Fv7/KWusicf
+ W91zf/4A4AuLF1bhN90AAAAASUVORK5CYII=
@@ -311,15 +311,15 @@
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
- YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHvSURBVDhP7Y7Ni1JhGMVvXadgWrWzRQyzTEFyFa7U0Wvg
- R3A3KgS1SLFeSbCPGe0uHFyMIEzgBXOVECi00VbOKGWg4yYiW4i1ujNIEVKkQVPaZJ7hGUhMnP+gAy88
- nPM7h5fj/msiQRDOMMbux2KxXjabhSRJHcbYJcaYWpIkhTzKiCH2n7JGoznlcDiSqVQK3W4XiqKgVqtR
- YVeSpHqr1RqS12g0QAyx1JkM6PX6K6FQ6Fu73e55vd4tQRBGfr8fsiwjGo2CbvIoy+fzHWKpMz2QjMfj
- A1mWA06nc9FgMHyvVqtoNpuo1+soFAogjzJiiKXOZECn090KBAL9dDp9TxTFitlsPrDZbBBF8ejRTR5l
- xBBLncmAVqu94HK53icSiX4ul/taLBaRyWQQDocRiUSO7vIGw0tx6c+LlQU8sy0ePDGdfjgZ4DiONxqN
- F+12+57P59sPBoMDxtgvt9t9zePxWB5dNQ3f3jVgUNrE+F0ZP57eweugZvTcoro9PXKstq288rO0Ccgu
- YO0ssLGML0kTSmZ+d5adq60V1Xj8pohp9WNqkD/LzlXFyn/Yf3wDiKkxXOXQW+XQucmjLPAfZ9m52vGc
- W391fen3p7VlfI4uQPGdQPWyarRtPflglj1WO57zkYqF36Nv04/+lg8BALcaCRX7gQ0AAAAASUVORK5C
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHvSURBVDhP7Y7Ni1JhGMVvXadgWrWzRQyzTEFyla0cx6sL
+ P6K7USGoRYr1SoJ9zGh3YbgYQZjAC+YqIURoo61slDLQcRORgWCt7gxShBRp0JQ2mSeegS4mzn/QgRce
+ zvmdw8tx/6XKZrOdYIzdicfj/VwuB0mSuoyxc4wxrSRJCnmUEUPsP2WdTnfM6XSm0uk0er0eFEVBvV6n
+ wo4kSY12uz0ir9lsghhiqaMOGI3GC+Fw+Gun0+n7fL6ngiCMA4EAZFlGLBYD3eRRVigUusRSZ3oglUgk
+ hrIsB10u16LJZPpWq9XQarXQaDRQLBZBHmXEEEsddcBgMFwPBoODTCZzWxTFqsVi2bfb7RBF8eDRTR5l
+ xBBLHXVAr9efcbvd75LJ5CCfz38plUrIZrOIRCKIRqMHd2WD4cXFpd/PVxfwxL64/2jl+H11gOM43mw2
+ n3U4HLt+v38vFAoNGWM/PR7PZa/Xa31wyTx6c+s8huVNTN5W8P3xTbwK6cbPrJob0yOHakvglR/lTUB2
+ A+sngY1lfE6toGzhd2bZuSqvaiaT1yVMaxDXgvxZdq6qAv9+7+FVIK7FaI1Df41D9xqPio3/MMvO1bb3
+ 1L2XV5Z+fVxfxqfYAhT/EdTsmvGWcPTuLHuotr2no1Urv0vfph/9Lf8B0zIZ8W7n4ScAAAAASUVORK5C
YII=
@@ -335,18 +335,33 @@
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
- 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
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAKZSURBVDhPhZBfSFNRHMfvY0RPEfQSFD2tngqh9WBZ+Ceb
+ 6S3b1Dmvf9BlmWRhhKNbKs5JWq7IktnDBNvUjC5J4spt5nRexd1zl5FChfPcQStGpOdaQXA5cdS9XBd9
+ 4bwcvp/v7/v7UdSm5twlWqG/lAP9ZfGZAUbh3SYl6GTifE8hx3ed1yZ8SSW6GbP4tCIm9JWCud5iNuQ0
+ aoKOfA3fo2d5hwFMdRfGAvazZjW3LjJ5AzbZhAg6AJaRHkC5TpTk2jBczZ2HK/sD92nbpJ2O+Tt0W5sI
+ 7lKOTA5FkAZAdAlAZBEldANIa9dFKF8TJdkkRn7sm+ikga9Nx6l5CrjL4nO9RWw4ivIBRA0bsFy/CdcC
+ CdUAKGf4WnWspzU3ruapmX6TEnIYNaIkX05MTaxAGokQVZMWnsYsjb89W1Hz1LSrWCEHI0YCgmX5CgkT
+ ILq4/iehqjCUC0mAz5a5NSDoNMX5x3pWkNayN1qgmnU4isxAQpUiXC0XJHR89GYm67FkbV1hulvPTXcZ
+ ADmUCOWCTbBKlFYrCAwgot9Ff+4Zbj79e6QhfVbNUwF7nnbqER1720nbhKVfe8WofJJUFqFsCEOUSmBv
+ R96f+aE67K8/gV/UpRrVGdR4e545YKdjvjs5YKzlFEv2JW/Uks6O381RFl5ZcDTkwEtT97C3hcYvK7W7
+ 1RmU36bTvrHqOE9rVpwcy2vNUIZvn1oZaz6DP4234a8f+vC3RRf+ONaEh5hjijtZSDJxV9OYic4iHAna
+ cex9L17mH+LZJxXYlqn5PHwhZbvan1TPa1IZr/UcXhy5hRdGGvHkgwI8VH34+zPDwR1q7z81aD7CuEpS
+ 8OumbDxQrv3iMqbsUnv+q8HKozt7ig5ZnWVp2xJ/fwEyO6SwopDsIwAAAABJRU5ErkJggg==
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIFSURBVDhPpZLtS1NhGMbPPxJmmlYSgqHiKzGU1EDxg4iK
+ YKyG2WBogqMYJQOtCEVRFBGdTBCJfRnkS4VaaWNT5sqx1BUxRXxDHYxAJLvkusEeBaPAB+5z4Jzn+t3X
+ /aLhnEfjo8m+dCoa+7/C3O2Hqe0zDC+8KG+cRZHZhdzaaWTVTCLDMIY0vfM04Nfh77/G/sEhwpEDbO3t
+ I7TxE8urEVy99fT/AL5gWDLrTB/hnF4XsW0khCu5ln8DmJliT2AXrcNBsU1gj/MH4nMeKwBrPktM28xM
+ cX79DFKrHHD5d9D26hvicx4pABt2lpg10zYzU0zr7+e3xXGcrkEB2O2TNec9nJFwB3alZn5jZorfeDZh
+ 6Q3g8s06BeCoKF4MRURoH1+BY2oNCbeb0TIclIYxOhzf8frTOuo7FxCbbVIAzpni0iceEc8vhzEwGkJD
+ lx83ymxifejdKjRNk/8PWnyIyTQqAJek0jqHwfEVscu31baIu8+90sTE4nY025dQ2/5FIPpnXlzKuK8A
+ HBUzHot52djqQ6HZhfR7IwK4mKpHtvEDMqvfCiQ6zaAAXM8x94aIWTNrLLG4kVUzgaTSPlzLtyJOZxbb
+ 1wtfyg4Q+AfA3aZlButjSfxGcUJBk4g5tuP3haQKRKXcUQDOmbvNTpPOJeFFjordZmbWTNvMTHFUcpUC
+ nOccAdABIDXXE1nzAAAAAElFTkSuQmCC
diff --git a/AGVLogic/AGVMapEditor/Properties/AssemblyInfo.cs b/AGVLogic/AGVMapEditor/Properties/AssemblyInfo.cs
index 7ef9156..59fbba6 100644
--- a/AGVLogic/AGVMapEditor/Properties/AssemblyInfo.cs
+++ b/AGVLogic/AGVMapEditor/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
// 기본값으로 할 수 있습니다.
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
\ No newline at end of file
+[assembly: AssemblyVersion("26.02.10.0900")]
+[assembly: AssemblyFileVersion("26.02.10.0900")]
\ No newline at end of file
diff --git a/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Events.cs b/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Events.cs
index 8d87a4f..af87165 100644
--- a/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Events.cs
+++ b/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Events.cs
@@ -478,8 +478,32 @@ namespace AGVNavigationCore.Controls
// But this method draws normal first.
// So I should refactor to calculate path first, then draw?
// Or just draw highlight on top with alpha?
- // Let's draw highlight on top with non-filled center? No, it's a line.
- // I'll draw highlight on top for now, maybe with alpha.
+ // Let's draw highlight on top for now, maybe with alpha.
+ }
+
+ // 선택된 마그넷 핸들 그리기
+ if (magnet == _selectedNode && _canvasMode == CanvasMode.Edit)
+ {
+ using (var handleBrush = new SolidBrush(Color.White))
+ using (var handlePen = new Pen(Color.Black, 1))
+ {
+ float size = HANDLE_SIZE / _zoomFactor;
+ float half = size / 2;
+
+ // 시작점, 끝점 핸들
+ g.FillRectangle(handleBrush, startPoint.X - half, startPoint.Y - half, size, size);
+ g.DrawRectangle(handlePen, startPoint.X - half, startPoint.Y - half, size, size);
+ g.FillRectangle(handleBrush, endPoint.X - half, endPoint.Y - half, size, size);
+ g.DrawRectangle(handlePen, endPoint.X - half, endPoint.Y - half, size, size);
+
+ // 제어점 핸들 (곡선일 경우)
+ if (magnet.ControlPoint != null)
+ {
+ var cp = magnet.ControlPoint;
+ g.FillRectangle(handleBrush, (float)cp.X - half, (float)cp.Y - half, size, size);
+ g.DrawRectangle(handlePen, (float)cp.X - half, (float)cp.Y - half, size, size);
+ }
+ }
}
}
@@ -488,11 +512,10 @@ namespace AGVNavigationCore.Controls
if (_marks == null) return; // _marks 리스트 사용
int sensorSize = 12; // 크기 설정
- int lineLength = 20; // 선 길이 설정
- int halfLength = lineLength / 2;
-
foreach (var mark in _marks)
{
+ int lineLength = (int)mark.Length; // 저장된 길이 사용
+ int halfLength = lineLength / 2;
Point p = mark.Position;
double radians = mark.Rotation * Math.PI / 180.0;
@@ -514,6 +537,22 @@ namespace AGVNavigationCore.Controls
g.DrawLine(highlightPen, p1, p2);
}
}
+
+ // 선택된 마크 핸들 그리기
+ if (mark == _selectedNode && _canvasMode == CanvasMode.Edit)
+ {
+ using (var handleBrush = new SolidBrush(Color.White))
+ using (var handlePen = new Pen(Color.Black, 1))
+ {
+ float size = HANDLE_SIZE / _zoomFactor;
+ float half = size / 2;
+
+ g.FillRectangle(handleBrush, p1.X - half, p1.Y - half, size, size);
+ g.DrawRectangle(handlePen, p1.X - half, p1.Y - half, size, size);
+ g.FillRectangle(handleBrush, p2.X - half, p2.Y - half, size, size);
+ g.DrawRectangle(handlePen, p2.X - half, p2.Y - half, size, size);
+ }
+ }
}
}
diff --git a/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Mouse.cs b/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Mouse.cs
index 45e91c5..6c45c2a 100644
--- a/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Mouse.cs
+++ b/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Mouse.cs
@@ -220,12 +220,28 @@ namespace AGVNavigationCore.Controls
{
if (_editMode == EditMode.Move)
{
+ // 0. 핸들 선택 확인 (이미 선택된 노드가 있을 때)
+ if (_selectedNode != null)
+ {
+ int handleIdx = GetHandleAt(worldPoint);
+ if (handleIdx != -1)
+ {
+ _dragHandleIndex = handleIdx;
+ _isDragging = true;
+ _isPanning = false;
+ Capture = true;
+ Invalidate();
+ return;
+ }
+ }
+
// 1. 노드 선택 확인
var hitNode = GetItemAt(worldPoint);
if (hitNode != null)
{
_isDragging = true;
_isPanning = false;
+ _dragHandleIndex = -1; // 노드 전체 드래그
_selectedNode = hitNode;
_dragStartPosition = hitNode.Position;
_dragOffset = new Point(worldPoint.X - hitNode.Position.X, worldPoint.Y - hitNode.Position.Y);
@@ -322,8 +338,38 @@ namespace AGVNavigationCore.Controls
// 노드 드래그
if (_selectedNode != null)
{
- _selectedNode.Position = newPosition;
- NodeMoved?.Invoke(this, _selectedNode);
+ if (_dragHandleIndex != -1)
+ {
+ // 핸들 드래그 (포인트별 수정)
+ if (_selectedNode is MapMagnet magnet)
+ {
+ if (_dragHandleIndex == 0) magnet.StartPoint = newPosition;
+ else if (_dragHandleIndex == 1) magnet.EndPoint = newPosition;
+ else if (_dragHandleIndex == 2 && magnet.ControlPoint != null)
+ {
+ magnet.ControlPoint.X = newPosition.X;
+ magnet.ControlPoint.Y = newPosition.Y;
+ }
+ }
+ else if (_selectedNode is MapMark mark)
+ {
+ // 마크는 중심점 대비 각도와 길이를 계산하여 수정
+ var dx = newPosition.X - mark.Position.X;
+ var dy = newPosition.Y - mark.Position.Y;
+
+ // 핸들 인덱스에 따라 각도 반전 (p1 vs p2)
+ if (_dragHandleIndex == 0) { dx = -dx; dy = -dy; }
+
+ mark.Rotation = Math.Atan2(dy, dx) * 180.0 / Math.PI;
+ mark.Length = Math.Sqrt(dx * dx + dy * dy) * 2;
+ }
+ }
+ else
+ {
+ // 노드 전체 드래그
+ _selectedNode.Position = newPosition;
+ NodeMoved?.Invoke(this, _selectedNode);
+ }
moved = true;
}
@@ -352,6 +398,7 @@ namespace AGVNavigationCore.Controls
if (_isDragging && _canvasMode == CanvasMode.Edit)
{
_isDragging = false;
+ _dragHandleIndex = -1;
Capture = false; // 🔥 마우스 캡처 해제
Cursor = GetCursorForMode(_editMode);
}
@@ -463,6 +510,25 @@ namespace AGVNavigationCore.Controls
}
}
+ if (_marks != null)
+ {
+ for (int i = _marks.Count - 1; i >= 0; i--)
+ {
+ var node = _marks[i];
+ if (IsPointInNode(worldPoint, node))
+ return node;
+ }
+ }
+
+ if (_magnets != null)
+ {
+ for (int i = _magnets.Count - 1; i >= 0; i--)
+ {
+ var node = _magnets[i];
+ if (IsPointInNode(worldPoint, node))
+ return node;
+ }
+ }
return null;
}
@@ -477,6 +543,14 @@ namespace AGVNavigationCore.Controls
{
return IsPointInImage(point, image);
}
+ if (node is MapMark mark)
+ {
+ return IsPointInMark(point, mark);
+ }
+ if (node is MapMagnet magnet)
+ {
+ return IsPointInMagnet(point, magnet);
+ }
// 라벨과 이미지는 별도 리스트로 관리되므로 여기서 처리하지 않음
// 하지만 혹시 모를 하위 호환성을 위해 타입 체크는 유지하되,
// 실제 로직은 CircularNode 등으로 분기
@@ -648,6 +722,55 @@ namespace AGVNavigationCore.Controls
return imageRect.Contains(point);
}
+ private bool IsPointInMark(Point point, MapMark mark)
+ {
+ int lineLength = (int)mark.Length;
+ int halfLength = lineLength / 2;
+ double radians = mark.Rotation * Math.PI / 180.0;
+ int dx = (int)(halfLength * Math.Cos(radians));
+ int dy = (int)(halfLength * Math.Sin(radians));
+
+ Point p1 = new Point(mark.Position.X - dx, mark.Position.Y - dy);
+ Point p2 = new Point(mark.Position.X + dx, mark.Position.Y + dy);
+
+ // 마크 선택을 위해 약간 넉넉한 히트 영역 (7픽셀)
+ return CalculatePointToLineDistance(point, p1, p2) <= 7 / _zoomFactor;
+ }
+
+ private bool IsPointInMagnet(Point point, MapMagnet magnet)
+ {
+ // 마그넷은 두꺼우므로 (Pen Width 15) 절반인 7.5 정도를 히트 영역으로 잡음
+ float hitThreshold = Math.Max(8f, 12f / _zoomFactor);
+
+ if (magnet.ControlPoint != null)
+ {
+ // 베지어 곡선 정밀 샘플링 (10개 세그먼트)
+ Point prevPoint = magnet.StartPoint;
+ for (int i = 1; i <= 10; i++)
+ {
+ float t = i / 10f;
+ // Quadratic Bezier: (1-t)^2*P0 + 2(1-t)t*P1 + t^2*P2
+ float u = 1 - t;
+ float tt = t * t;
+ float uu = u * u;
+
+ float x = uu * magnet.StartPoint.X + 2 * u * t * (float)magnet.ControlPoint.X + tt * magnet.EndPoint.X;
+ float y = uu * magnet.StartPoint.Y + 2 * u * t * (float)magnet.ControlPoint.Y + tt * magnet.EndPoint.Y;
+ Point currentPoint = new Point((int)x, (int)y);
+
+ if (CalculatePointToLineDistance(point, prevPoint, currentPoint) <= hitThreshold)
+ return true;
+
+ prevPoint = currentPoint;
+ }
+ return false;
+ }
+ else
+ {
+ return CalculatePointToLineDistance(point, magnet.StartPoint, magnet.EndPoint) <= hitThreshold;
+ }
+ }
+
//private MapLabel GetLabelAt(Point worldPoint)
//{
// if (_labels == null) return null;
@@ -833,7 +956,7 @@ namespace AGVNavigationCore.Controls
///
/// 중복되지 않는 고유한 NodeId 생성
///
- private string GenerateUniqueNodeId()
+ public string GenerateUniqueNodeId()
{
string nodeId;
int counter = _nodeCounter;
@@ -1053,8 +1176,8 @@ namespace AGVNavigationCore.Controls
var C = lineEnd.X - lineStart.X;
var D = lineEnd.Y - lineStart.Y;
- var dot = A * C + B * D;
- var lenSq = C * C + D * D;
+ var dot = (double)A * C + (double)B * D;
+ var lenSq = (double)C * C + (double)D * D;
if (lenSq == 0) return CalculateDistance(point, lineStart);
@@ -1102,6 +1225,39 @@ namespace AGVNavigationCore.Controls
}
}
+ private int GetHandleAt(Point worldPoint)
+ {
+ if (_selectedNode == null) return -1;
+
+ float hitTolerance = (HANDLE_SIZE + 4) / _zoomFactor;
+
+ if (_selectedNode is MapMagnet magnet)
+ {
+ if (CalculateDistance(worldPoint, magnet.StartPoint) <= hitTolerance) return 0;
+ if (CalculateDistance(worldPoint, magnet.EndPoint) <= hitTolerance) return 1;
+ if (magnet.ControlPoint != null)
+ {
+ if (CalculateDistance(worldPoint, new Point((int)magnet.ControlPoint.X, (int)magnet.ControlPoint.Y)) <= hitTolerance) return 2;
+ }
+ }
+ else if (_selectedNode is MapMark mark)
+ {
+ int lineLength = (int)mark.Length;
+ int halfLength = lineLength / 2;
+ double radians = mark.Rotation * Math.PI / 180.0;
+ int dx = (int)(halfLength * Math.Cos(radians));
+ int dy = (int)(halfLength * Math.Sin(radians));
+
+ Point p1 = new Point(mark.Position.X - dx, mark.Position.Y - dy);
+ Point p2 = new Point(mark.Position.X + dx, mark.Position.Y + dy);
+
+ if (CalculateDistance(worldPoint, p1) <= hitTolerance) return 0;
+ if (CalculateDistance(worldPoint, p2) <= hitTolerance) return 1;
+ }
+
+ return -1;
+ }
+
#endregion
#region View Control Methods
diff --git a/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.cs b/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.cs
index fd30f2f..4458ace 100644
--- a/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.cs
+++ b/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.cs
@@ -109,6 +109,8 @@ namespace AGVNavigationCore.Controls
private MapNode _connectionStartNode;
private Point _connectionEndPoint;
private int _mouseMoveCounter = 0; // 디버그용: MouseMove 실행 횟수
+ private int _dragHandleIndex = -1; // 드래그 중인 핸들 인덱스
+ private const int HANDLE_SIZE = 8; // 편집 핸들 크기
// 영역 선택 관련
private bool _isAreaSelecting;
@@ -341,6 +343,17 @@ namespace AGVNavigationCore.Controls
Invalidate();
}
+ [Browsable(false)]
+ public PointF PanOffset
+ {
+ get => _panOffset;
+ set
+ {
+ _panOffset = value;
+ Invalidate();
+ }
+ }
+
///
/// 그리드 표시 여부
///
diff --git a/AGVLogic/AGVNavigationCore/Models/MapMagnet.cs b/AGVLogic/AGVNavigationCore/Models/MapMagnet.cs
index 1384890..5556b00 100644
--- a/AGVLogic/AGVNavigationCore/Models/MapMagnet.cs
+++ b/AGVLogic/AGVNavigationCore/Models/MapMagnet.cs
@@ -56,17 +56,25 @@ namespace AGVNavigationCore.Models
}
///
- /// 시작점 Point 반환
+ /// 시작점 Point 반환 및 설정
///
[Browsable(false)]
[JsonIgnore]
- public Point StartPoint => new Point((int)P1.X, (int)P1.Y);
+ public Point StartPoint
+ {
+ get => new Point((int)P1.X, (int)P1.Y);
+ set { P1.X = value.X; P1.Y = value.Y; }
+ }
///
- /// 끝점 Point 반환
+ /// 끝점 Point 반환 및 설정
///
[Browsable(false)]
[JsonIgnore]
- public Point EndPoint => new Point((int)P2.X, (int)P2.Y);
+ public Point EndPoint
+ {
+ get => new Point((int)P2.X, (int)P2.Y);
+ set { P2.X = value.X; P2.Y = value.Y; }
+ }
}
}
diff --git a/AGVLogic/AGVNavigationCore/Models/MapMark.cs b/AGVLogic/AGVNavigationCore/Models/MapMark.cs
index 6cd657e..4a2e5d1 100644
--- a/AGVLogic/AGVNavigationCore/Models/MapMark.cs
+++ b/AGVLogic/AGVNavigationCore/Models/MapMark.cs
@@ -33,5 +33,9 @@ namespace AGVNavigationCore.Models
[Category("위치 정보")]
[Description("마크의 회전 각도")]
public double Rotation { get; set; }
+
+ [Category("위치 정보")]
+ [Description("마크의 길이")]
+ public double Length { get; set; } = 20.0;
}
}
diff --git a/AGVLogic/AGVSimulator/Forms/SimulatorForm.Designer.cs b/AGVLogic/AGVSimulator/Forms/SimulatorForm.Designer.cs
index a5ad18b..f3e8cc4 100644
--- a/AGVLogic/AGVSimulator/Forms/SimulatorForm.Designer.cs
+++ b/AGVLogic/AGVSimulator/Forms/SimulatorForm.Designer.cs
@@ -55,6 +55,7 @@ namespace AGVSimulator.Forms
this.맵다른이름으로저장ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.launchMapEditorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.btSelectMapEditor = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.simulationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@@ -120,7 +121,7 @@ namespace AGVSimulator.Forms
this._liftDirectionLabel = new System.Windows.Forms.Label();
this._motorDirectionLabel = new System.Windows.Forms.Label();
this.timer1 = new System.Windows.Forms.Timer(this.components);
- this.btSelectMapEditor = new System.Windows.Forms.ToolStripMenuItem();
+ this.sbFile = new System.Windows.Forms.ToolStripStatusLabel();
this._menuStrip.SuspendLayout();
this._toolStrip.SuspendLayout();
this._statusStrip.SuspendLayout();
@@ -205,6 +206,13 @@ namespace AGVSimulator.Forms
this.launchMapEditorToolStripMenuItem.Text = "MapEditor 실행(&M)";
this.launchMapEditorToolStripMenuItem.Click += new System.EventHandler(this.OnLaunchMapEditor_Click);
//
+ // btSelectMapEditor
+ //
+ this.btSelectMapEditor.Name = "btSelectMapEditor";
+ this.btSelectMapEditor.Size = new System.Drawing.Size(221, 22);
+ this.btSelectMapEditor.Text = "Mapeditor 선택";
+ this.btSelectMapEditor.Click += new System.EventHandler(this.btSelectMapEditor_Click);
+ //
// toolStripSeparator4
//
this.toolStripSeparator4.Name = "toolStripSeparator4";
@@ -434,7 +442,8 @@ namespace AGVSimulator.Forms
this._statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this._statusLabel,
this._coordLabel,
- this.prb1});
+ this.prb1,
+ this.sbFile});
this._statusStrip.Location = new System.Drawing.Point(0, 689);
this._statusStrip.Name = "_statusStrip";
this._statusStrip.Size = new System.Drawing.Size(1248, 22);
@@ -816,12 +825,11 @@ namespace AGVSimulator.Forms
this.timer1.Interval = 500;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
- // btSelectMapEditor
+ // sbFile
//
- this.btSelectMapEditor.Name = "btSelectMapEditor";
- this.btSelectMapEditor.Size = new System.Drawing.Size(221, 22);
- this.btSelectMapEditor.Text = "Mapeditor 선택";
- this.btSelectMapEditor.Click += new System.EventHandler(this.btSelectMapEditor_Click);
+ this.sbFile.Name = "sbFile";
+ this.sbFile.Size = new System.Drawing.Size(17, 17);
+ this.sbFile.Text = "--";
//
// SimulatorForm
//
@@ -937,5 +945,6 @@ namespace AGVSimulator.Forms
private System.Windows.Forms.PropertyGrid propertyNode;
private System.Windows.Forms.Button btPath2;
private System.Windows.Forms.ToolStripMenuItem btSelectMapEditor;
+ private System.Windows.Forms.ToolStripStatusLabel sbFile;
}
}
\ No newline at end of file
diff --git a/AGVLogic/AGVSimulator/Forms/SimulatorForm.cs b/AGVLogic/AGVSimulator/Forms/SimulatorForm.cs
index b58c104..ea25bee 100644
--- a/AGVLogic/AGVSimulator/Forms/SimulatorForm.cs
+++ b/AGVLogic/AGVSimulator/Forms/SimulatorForm.cs
@@ -876,7 +876,7 @@ namespace AGVSimulator.Forms
try
{
var result = MapLoader.LoadMapFromFile(filePath);
-
+ sbFile.Text = filePath;
if (result.Success)
{
Console.WriteLine($"Map File Load : {filePath}");
diff --git a/HMI/Project/StateMachine/_AGV.cs b/HMI/Project/StateMachine/_AGV.cs
index 48dbb49..73168bc 100644
--- a/HMI/Project/StateMachine/_AGV.cs
+++ b/HMI/Project/StateMachine/_AGV.cs
@@ -16,6 +16,34 @@ namespace Project
public partial class fMain
{
+ private void AGV_TurnComplete(object sender, arDev.Narumi.TurnEventArgs e)
+ {
+ //턴작업이완료되었을때 발생된다.
+ PUB.log.Add($"AGV Turn Complete:{e.Direction}");
+
+ //일반노드에서 턴작업이 진행되었다면, 이전경로와 현재경로의 모터 방향을 바꿔준다(일반노드에서만 사용)
+ if (PUB._virtualAGV.CurrentNode != null && PUB._virtualAGV.CurrentNode.StationType == StationType.Normal)
+ {
+ var prevnodeid = PUB._virtualAGV.PrevNode;//.Id;
+ var currnodeid = PUB._virtualAGV.CurrentNode;//.Id;
+
+ //현재 방향과 반대로 모터방향을 셋팅한다. 기존에 Fwd로 왔다면 BWD로 온것으로 처리
+ var motdir = PUB._virtualAGV.PrevDirection == AgvDirection.Forward ? AgvDirection.Backward : AgvDirection.Forward;
+
+ PUB.log.Add($"일반노드에서 TURN 완료({e.Direction}) 이전노드:{prevnodeid.ID2},현재노드:{currnodeid.ID2},이전방향:{PUB._virtualAGV.PrevDirection},변경방향:{motdir}");
+
+ //이전노드이동한것으로처리
+ PUB._mapCanvas.SetAGVPosition(PUB.setting.MCID, prevnodeid, motdir);
+ PUB._virtualAGV.SetPosition(prevnodeid, motdir);
+
+ //현재노드이동한것으로처리
+ PUB._mapCanvas.SetAGVPosition(PUB.setting.MCID, currnodeid, motdir);
+ PUB._virtualAGV.SetPosition(currnodeid, motdir);
+ }
+
+ }
+
+
private void AGV_Message(object sender, arDev.Narumi.MessageEventArgs e)
{
if (e.MsgType == arDev.NarumiSerialComm.MessageType.Normal)
diff --git a/HMI/Project/fMain.cs b/HMI/Project/fMain.cs
index 3a7004d..a74d24a 100644
--- a/HMI/Project/fMain.cs
+++ b/HMI/Project/fMain.cs
@@ -166,6 +166,7 @@ namespace Project
PUB.AGV = new arDev.Narumi();
PUB.AGV.Message += AGV_Message;
PUB.AGV.DataReceive += AGV_DataReceive;
+ PUB.AGV.TurnComplete += AGV_TurnComplete;
//배터리관리시스템
PUB.BMS = new arDev.BMS();
@@ -261,6 +262,7 @@ namespace Project
PUB.AddEEDB("프로그램 시작");
}
+
void AutoLoadLastPosition()
{
PUB.log.Add("autoload last position");
diff --git a/HMI/SubProject/AGV/DataEventArgs.cs b/HMI/SubProject/AGV/DataEventArgs.cs
index a5a5c36..1052a43 100644
--- a/HMI/SubProject/AGV/DataEventArgs.cs
+++ b/HMI/SubProject/AGV/DataEventArgs.cs
@@ -13,6 +13,20 @@ namespace arDev
DataType = type;
}
}
+ public enum eTurnEvent
+ {
+ Left=0,
+ Right
+ }
+ public class TurnEventArgs : EventArgs
+ {
+ public eTurnEvent Direction { get; set; }
+ public TurnEventArgs(eTurnEvent data)
+ {
+ this.Direction = data;
+ }
+
+ }
}
diff --git a/HMI/SubProject/AGV/Narumi.cs b/HMI/SubProject/AGV/Narumi.cs
index 68bd663..4d1289c 100644
--- a/HMI/SubProject/AGV/Narumi.cs
+++ b/HMI/SubProject/AGV/Narumi.cs
@@ -71,7 +71,8 @@ namespace arDev
/// 분석완료된 데이터 이벤트
///
public event EventHandler DataReceive;
-
+ public event EventHandler TurnComplete;
+
#endregion
diff --git a/HMI/TestProject/Test_ACS/MainForm.Designer.cs b/HMI/TestProject/Test_ACS/MainForm.Designer.cs
index c573442..66e94f4 100644
--- a/HMI/TestProject/Test_ACS/MainForm.Designer.cs
+++ b/HMI/TestProject/Test_ACS/MainForm.Designer.cs
@@ -29,12 +29,7 @@ namespace Test_ACS
this.rbAGV2 = new System.Windows.Forms.RadioButton();
this.rbAGV1 = new System.Windows.Forms.RadioButton();
this.grpCommands = new System.Windows.Forms.GroupBox();
- this.button11 = new System.Windows.Forms.Button();
- this.button12 = new System.Windows.Forms.Button();
- this.btnLiftStop = new System.Windows.Forms.Button();
this.button8 = new System.Windows.Forms.Button();
- this.btnLiftDown = new System.Windows.Forms.Button();
- this.btnLiftUp = new System.Windows.Forms.Button();
this.button10 = new System.Windows.Forms.Button();
this.button7 = new System.Windows.Forms.Button();
this.button9 = new System.Windows.Forms.Button();
@@ -71,6 +66,11 @@ namespace Test_ACS
this.lblAlias = new System.Windows.Forms.Label();
this.txtRFID = new System.Windows.Forms.NumericUpDown();
this.lblRFID = new System.Windows.Forms.Label();
+ this.button11 = new System.Windows.Forms.Button();
+ this.button12 = new System.Windows.Forms.Button();
+ this.btnLiftStop = new System.Windows.Forms.Button();
+ this.btnLiftDown = new System.Windows.Forms.Button();
+ this.btnLiftUp = new System.Windows.Forms.Button();
this.grpLogs = new System.Windows.Forms.GroupBox();
this.tabLogs = new System.Windows.Forms.TabControl();
this.tabRX = new System.Windows.Forms.TabPage();
@@ -245,36 +245,6 @@ namespace Test_ACS
this.grpCommands.TabStop = false;
this.grpCommands.Text = "ACS 명령";
//
- // button11
- //
- this.button11.Location = new System.Drawing.Point(451, 200);
- this.button11.Name = "button11";
- this.button11.Size = new System.Drawing.Size(100, 43);
- this.button11.TabIndex = 18;
- this.button11.Text = "전자석 OFF";
- this.button11.UseVisualStyleBackColor = true;
- this.button11.Click += new System.EventHandler(this.button11_Click);
- //
- // button12
- //
- this.button12.Location = new System.Drawing.Point(451, 155);
- this.button12.Name = "button12";
- this.button12.Size = new System.Drawing.Size(100, 43);
- this.button12.TabIndex = 17;
- this.button12.Text = "전자석 ON";
- this.button12.UseVisualStyleBackColor = true;
- this.button12.Click += new System.EventHandler(this.button12_Click);
- //
- // btnLiftStop
- //
- this.btnLiftStop.Location = new System.Drawing.Point(451, 110);
- this.btnLiftStop.Name = "btnLiftStop";
- this.btnLiftStop.Size = new System.Drawing.Size(100, 43);
- this.btnLiftStop.TabIndex = 2;
- this.btnLiftStop.Text = "리프트 정지";
- this.btnLiftStop.UseVisualStyleBackColor = true;
- this.btnLiftStop.Click += new System.EventHandler(this.btnLiftStop_Click);
- //
// button8
//
this.button8.Location = new System.Drawing.Point(102, 264);
@@ -285,26 +255,6 @@ namespace Test_ACS
this.button8.UseVisualStyleBackColor = true;
this.button8.Click += new System.EventHandler(this.button8_Click);
//
- // btnLiftDown
- //
- this.btnLiftDown.Location = new System.Drawing.Point(451, 65);
- this.btnLiftDown.Name = "btnLiftDown";
- this.btnLiftDown.Size = new System.Drawing.Size(100, 43);
- this.btnLiftDown.TabIndex = 1;
- this.btnLiftDown.Text = "리프트 DN";
- this.btnLiftDown.UseVisualStyleBackColor = true;
- this.btnLiftDown.Click += new System.EventHandler(this.btnLiftDown_Click);
- //
- // btnLiftUp
- //
- this.btnLiftUp.Location = new System.Drawing.Point(451, 20);
- this.btnLiftUp.Name = "btnLiftUp";
- this.btnLiftUp.Size = new System.Drawing.Size(100, 43);
- this.btnLiftUp.TabIndex = 0;
- this.btnLiftUp.Text = "리프트 UP";
- this.btnLiftUp.UseVisualStyleBackColor = true;
- this.btnLiftUp.Click += new System.EventHandler(this.btnLiftUp_Click);
- //
// button10
//
this.button10.Location = new System.Drawing.Point(102, 229);
@@ -655,12 +605,6 @@ namespace Test_ACS
// txtAlias
//
this.txtAlias.Font = new System.Drawing.Font("Consolas", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.txtAlias.Items.AddRange(new object[] {
- "LOADER",
- "UNLOADER",
- "CLEANNER",
- "CHARGER1",
- "CHARGER2"});
this.txtAlias.Location = new System.Drawing.Point(86, 49);
this.txtAlias.Name = "txtAlias";
this.txtAlias.Size = new System.Drawing.Size(101, 27);
@@ -706,6 +650,56 @@ namespace Test_ACS
this.lblRFID.TabIndex = 0;
this.lblRFID.Text = "RFID 번호:";
//
+ // button11
+ //
+ this.button11.Location = new System.Drawing.Point(451, 200);
+ this.button11.Name = "button11";
+ this.button11.Size = new System.Drawing.Size(100, 43);
+ this.button11.TabIndex = 18;
+ this.button11.Text = "전자석 OFF";
+ this.button11.UseVisualStyleBackColor = true;
+ this.button11.Click += new System.EventHandler(this.button11_Click);
+ //
+ // button12
+ //
+ this.button12.Location = new System.Drawing.Point(451, 155);
+ this.button12.Name = "button12";
+ this.button12.Size = new System.Drawing.Size(100, 43);
+ this.button12.TabIndex = 17;
+ this.button12.Text = "전자석 ON";
+ this.button12.UseVisualStyleBackColor = true;
+ this.button12.Click += new System.EventHandler(this.button12_Click);
+ //
+ // btnLiftStop
+ //
+ this.btnLiftStop.Location = new System.Drawing.Point(451, 110);
+ this.btnLiftStop.Name = "btnLiftStop";
+ this.btnLiftStop.Size = new System.Drawing.Size(100, 43);
+ this.btnLiftStop.TabIndex = 2;
+ this.btnLiftStop.Text = "리프트 정지";
+ this.btnLiftStop.UseVisualStyleBackColor = true;
+ this.btnLiftStop.Click += new System.EventHandler(this.btnLiftStop_Click);
+ //
+ // btnLiftDown
+ //
+ this.btnLiftDown.Location = new System.Drawing.Point(451, 65);
+ this.btnLiftDown.Name = "btnLiftDown";
+ this.btnLiftDown.Size = new System.Drawing.Size(100, 43);
+ this.btnLiftDown.TabIndex = 1;
+ this.btnLiftDown.Text = "리프트 DN";
+ this.btnLiftDown.UseVisualStyleBackColor = true;
+ this.btnLiftDown.Click += new System.EventHandler(this.btnLiftDown_Click);
+ //
+ // btnLiftUp
+ //
+ this.btnLiftUp.Location = new System.Drawing.Point(451, 20);
+ this.btnLiftUp.Name = "btnLiftUp";
+ this.btnLiftUp.Size = new System.Drawing.Size(100, 43);
+ this.btnLiftUp.TabIndex = 0;
+ this.btnLiftUp.Text = "리프트 UP";
+ this.btnLiftUp.UseVisualStyleBackColor = true;
+ this.btnLiftUp.Click += new System.EventHandler(this.btnLiftUp_Click);
+ //
// grpLogs
//
this.grpLogs.Controls.Add(this.tabLogs);
diff --git a/HMI/TestProject/Test_ACS/MainForm.cs b/HMI/TestProject/Test_ACS/MainForm.cs
index bb63671..f7fdd61 100644
--- a/HMI/TestProject/Test_ACS/MainForm.cs
+++ b/HMI/TestProject/Test_ACS/MainForm.cs
@@ -21,6 +21,22 @@ namespace Test_ACS
InitializeComponent();
InitializeProtocol();
LoadPortList();
+
+ txtAlias.Items.Clear();
+ this.txtAlias.Items.AddRange(new[] {
+ "LOADER",
+ "PLATING",
+ "CLEANER",
+ "CHARGER",
+ "BUFFER1",
+ "BUFFER2",
+ "BUFFER3",
+ "BUFFER4",
+ "BUFFER5",
+ "BUFFER6",
+ });
+ this.txtAlias.Text = "LOADER";
+
}
@@ -611,19 +627,7 @@ namespace Test_ACS
private void MainForm_Load(object sender, EventArgs e)
{
- this.txtAlias.Items.AddRange(new[] {
- "LOADER",
- "UNLOADER",
- "CLEANNER",
- "CHARGER1",
- "CHARGER2",
- "BUFFER1",
- "BUFFER2",
- "BUFFER3",
- "BUFFER4",
- "BUFFER5",
- "BUFFER6",
- });
+
}
}
}
diff --git a/NewMap.json b/NewMap.json
index 558b572..dd9904e 100644
--- a/NewMap.json
+++ b/NewMap.json
@@ -1,20 +1,19 @@
{
"Nodes": [
{
- "Text": "Unloader",
+ "Text": "CLEANER",
"StationType": 3,
"CanDocking": true,
"DockDirection": 2,
"MagnetDirections": {},
"ConnectedNodes": [
- "12",
- "N028"
+ "10"
],
"CanTurnLeft": true,
"CanTurnRight": true,
"DisableCross": false,
"SpeedLimit": 0,
- "AliasName": "",
+ "AliasName": "CLEANER",
"IsActive": true,
"RfidId": 30,
"NodeTextForeColor": "White",
@@ -22,23 +21,22 @@
"ID2": "0030(*N001)",
"Id": "N001",
"Type": 0,
- "Position": "298, 270"
+ "Position": "395, 269"
},
{
- "Text": "Cleaner",
+ "Text": "PLATING",
"StationType": 2,
"CanDocking": true,
"DockDirection": 2,
"MagnetDirections": {},
"ConnectedNodes": [
- "5",
- "N030"
+ "5"
],
"CanTurnLeft": true,
"CanTurnRight": true,
"DisableCross": false,
"SpeedLimit": 0,
- "AliasName": "",
+ "AliasName": "PLATING",
"IsActive": true,
"RfidId": 11,
"NodeTextForeColor": "",
@@ -46,82 +44,10 @@
"ID2": "0011(*N010)",
"Id": "N010",
"Type": 0,
- "Position": "298, 446"
+ "Position": "350, 506"
},
{
- "Text": "Loader",
- "StationType": 1,
- "CanDocking": true,
- "DockDirection": 2,
- "MagnetDirections": {},
- "ConnectedNodes": [
- "N026",
- "N029"
- ],
- "CanTurnLeft": true,
- "CanTurnRight": true,
- "DisableCross": false,
- "SpeedLimit": 0,
- "AliasName": "",
- "IsActive": true,
- "RfidId": 8,
- "NodeTextForeColor": "",
- "NodeTextFontSize": 7.0,
- "ID2": "0008(*N014)",
- "Id": "N014",
- "Type": 0,
- "Position": "520, 653"
- },
- {
- "Text": "Charger #1",
- "StationType": 5,
- "CanDocking": true,
- "DockDirection": 1,
- "MagnetDirections": {},
- "ConnectedNodes": [
- "8",
- "13"
- ],
- "CanTurnLeft": true,
- "CanTurnRight": true,
- "DisableCross": false,
- "SpeedLimit": 0,
- "AliasName": "",
- "IsActive": true,
- "RfidId": 15,
- "NodeTextForeColor": "",
- "NodeTextFontSize": 7.0,
- "ID2": "0015(*N019)",
- "Id": "N019",
- "Type": 0,
- "Position": "405, 351"
- },
- {
- "Text": "Charger #2",
- "StationType": 6,
- "CanDocking": true,
- "DockDirection": 2,
- "MagnetDirections": {},
- "ConnectedNodes": [
- "6",
- "N014"
- ],
- "CanTurnLeft": true,
- "CanTurnRight": true,
- "DisableCross": false,
- "SpeedLimit": 0,
- "AliasName": "",
- "IsActive": true,
- "RfidId": 19,
- "NodeTextForeColor": "",
- "NodeTextFontSize": 7.0,
- "ID2": "0019(*N026)",
- "Id": "N026",
- "Type": 0,
- "Position": "520, 576"
- },
- {
- "Text": "Buffer4",
+ "Text": "Buffer1",
"StationType": 4,
"CanDocking": true,
"DockDirection": 2,
@@ -134,7 +60,7 @@
"CanTurnRight": true,
"DisableCross": false,
"SpeedLimit": 0,
- "AliasName": "",
+ "AliasName": "BUFFER1",
"IsActive": true,
"RfidId": 34,
"NodeTextForeColor": "",
@@ -142,10 +68,10 @@
"ID2": "0034(*N018)",
"Id": "N018",
"Type": 0,
- "Position": "213, 630"
+ "Position": "238, 627"
},
{
- "Text": "Buffer3",
+ "Text": "Buffer2",
"StationType": 4,
"CanDocking": true,
"DockDirection": 2,
@@ -158,7 +84,7 @@
"CanTurnRight": true,
"DisableCross": false,
"SpeedLimit": 0,
- "AliasName": "",
+ "AliasName": "BUFFER2",
"IsActive": true,
"RfidId": 33,
"NodeTextForeColor": "",
@@ -166,10 +92,10 @@
"ID2": "0033(*N005)",
"Id": "N005",
"Type": 0,
- "Position": "113, 629"
+ "Position": "164, 627"
},
{
- "Text": "Buffer2",
+ "Text": "Buffer3",
"StationType": 4,
"CanDocking": true,
"DockDirection": 2,
@@ -182,7 +108,7 @@
"CanTurnRight": true,
"DisableCross": false,
"SpeedLimit": 0,
- "AliasName": "",
+ "AliasName": "BUFFER3",
"IsActive": true,
"RfidId": 32,
"NodeTextForeColor": "",
@@ -190,23 +116,23 @@
"ID2": "0032(*N020)",
"Id": "N020",
"Type": 0,
- "Position": "38, 626"
+ "Position": "89, 629"
},
{
- "Text": "Buffer 1",
+ "Text": "Buffer4",
"StationType": 4,
"CanDocking": true,
"DockDirection": 2,
"MagnetDirections": {},
"ConnectedNodes": [
"N020",
- "N027"
+ "N028"
],
"CanTurnLeft": true,
"CanTurnRight": true,
"DisableCross": false,
"SpeedLimit": 0,
- "AliasName": "",
+ "AliasName": "BUFFER4",
"IsActive": true,
"RfidId": 31,
"NodeTextForeColor": "",
@@ -214,7 +140,7 @@
"ID2": "0031(*N021)",
"Id": "N021",
"Type": 0,
- "Position": "-54, 626"
+ "Position": "15, 629"
},
{
"Text": "",
@@ -238,7 +164,7 @@
"ID2": "0002(*1)",
"Id": "1",
"Type": 0,
- "Position": "285, 628"
+ "Position": "338, 625"
},
{
"Text": "",
@@ -248,7 +174,7 @@
"MagnetDirections": {},
"ConnectedNodes": [
"1",
- "3"
+ "4"
],
"CanTurnLeft": true,
"CanTurnRight": true,
@@ -262,7 +188,7 @@
"ID2": "0004(*2)",
"Id": "2",
"Type": 0,
- "Position": "354, 628"
+ "Position": "406, 621"
},
{
"Text": "",
@@ -271,32 +197,8 @@
"DockDirection": 0,
"MagnetDirections": {},
"ConnectedNodes": [
- "2",
- "4"
- ],
- "CanTurnLeft": true,
- "CanTurnRight": true,
- "DisableCross": false,
- "SpeedLimit": 0,
- "AliasName": "",
- "IsActive": true,
- "RfidId": 3,
- "NodeTextForeColor": "",
- "NodeTextFontSize": 7.0,
- "ID2": "0003(*3)",
- "Id": "3",
- "Type": 0,
- "Position": "400, 578"
- },
- {
- "Text": "",
- "StationType": 0,
- "CanDocking": false,
- "DockDirection": 0,
- "MagnetDirections": {},
- "ConnectedNodes": [
- "3",
- "5"
+ "5",
+ "2"
],
"CanTurnLeft": true,
"CanTurnRight": true,
@@ -310,7 +212,7 @@
"ID2": "0005(*4)",
"Id": "4",
"Type": 0,
- "Position": "400, 499"
+ "Position": "435, 569"
},
{
"Text": "",
@@ -319,15 +221,14 @@
"DockDirection": 0,
"MagnetDirections": {
"4": 1,
- "6": 2,
"7": 1,
- "N010": 0
+ "N010": 2
},
"ConnectedNodes": [
"N010",
"4",
- "6",
- "7"
+ "7",
+ "8"
],
"CanTurnLeft": true,
"CanTurnRight": true,
@@ -341,28 +242,25 @@
"ID2": "0006(*5)",
"Id": "5",
"Type": 0,
- "Position": "462, 451"
+ "Position": "461, 503"
},
{
- "Text": "",
- "StationType": 0,
- "CanDocking": false,
- "DockDirection": 0,
+ "Text": "Loader",
+ "StationType": 1,
+ "CanDocking": true,
+ "DockDirection": 2,
"MagnetDirections": {
- "5": 1,
"7": 0,
"N026": 0
},
"ConnectedNodes": [
- "5",
- "7",
- "N026"
+ "7"
],
"CanTurnLeft": true,
"CanTurnRight": true,
"DisableCross": false,
"SpeedLimit": 0,
- "AliasName": "",
+ "AliasName": "LOADER",
"IsActive": true,
"RfidId": 13,
"NodeTextForeColor": "",
@@ -370,7 +268,7 @@
"ID2": "0013(*6)",
"Id": "6",
"Type": 0,
- "Position": "518, 519"
+ "Position": "521, 533"
},
{
"Text": "",
@@ -379,13 +277,10 @@
"DockDirection": 0,
"MagnetDirections": {
"5": 2,
- "8": 1,
- "6": 0,
- "9": 0
+ "6": 0
},
"ConnectedNodes": [
"5",
- "8",
"6",
"9"
],
@@ -401,28 +296,24 @@
"ID2": "0007(*7)",
"Id": "7",
"Type": 0,
- "Position": "517, 400"
+ "Position": "517, 404"
},
{
- "Text": "",
- "StationType": 0,
- "CanDocking": false,
- "DockDirection": 0,
+ "Text": "Charger",
+ "StationType": 5,
+ "CanDocking": true,
+ "DockDirection": 1,
"MagnetDirections": {
- "7": 2,
- "9": 1,
"N019": 0
},
"ConnectedNodes": [
- "7",
- "9",
- "N019"
+ "5"
],
"CanTurnLeft": true,
"CanTurnRight": true,
"DisableCross": false,
"SpeedLimit": 0,
- "AliasName": "",
+ "AliasName": "CHARGER",
"IsActive": true,
"RfidId": 9,
"NodeTextForeColor": "",
@@ -430,7 +321,7 @@
"ID2": "0009(*8)",
"Id": "8",
"Type": 0,
- "Position": "474, 353"
+ "Position": "439, 420"
},
{
"Text": "",
@@ -438,12 +329,9 @@
"CanDocking": false,
"DockDirection": 0,
"MagnetDirections": {
- "8": 2,
- "10": 0,
- "7": 0
+ "10": 0
},
"ConnectedNodes": [
- "8",
"10",
"7"
],
@@ -469,7 +357,7 @@
"MagnetDirections": {},
"ConnectedNodes": [
"9",
- "12"
+ "N001"
],
"CanTurnLeft": true,
"CanTurnRight": true,
@@ -483,54 +371,7 @@
"ID2": "0012(*10)",
"Id": "10",
"Type": 0,
- "Position": "458, 268"
- },
- {
- "Text": "",
- "StationType": 0,
- "CanDocking": false,
- "DockDirection": 0,
- "MagnetDirections": {},
- "ConnectedNodes": [
- "N001",
- "10"
- ],
- "CanTurnLeft": true,
- "CanTurnRight": true,
- "DisableCross": false,
- "SpeedLimit": 0,
- "AliasName": "",
- "IsActive": true,
- "RfidId": 16,
- "NodeTextForeColor": "",
- "NodeTextFontSize": 7.0,
- "ID2": "0016(*12)",
- "Id": "12",
- "Type": 0,
- "Position": "389, 270"
- },
- {
- "Text": "",
- "StationType": 0,
- "CanDocking": false,
- "DockDirection": 0,
- "MagnetDirections": {},
- "ConnectedNodes": [
- "N019"
- ],
- "CanTurnLeft": true,
- "CanTurnRight": true,
- "DisableCross": false,
- "SpeedLimit": 0,
- "AliasName": "",
- "IsActive": true,
- "RfidId": 17,
- "NodeTextForeColor": "",
- "NodeTextFontSize": 7.0,
- "ID2": "0017(*13)",
- "Id": "13",
- "Type": 0,
- "Position": "350, 353"
+ "Position": "490, 277"
},
{
"Text": "",
@@ -539,7 +380,7 @@
"DockDirection": 0,
"MagnetDirections": {},
"ConnectedNodes": [
- "N021"
+ "N029"
],
"CanTurnLeft": true,
"CanTurnRight": true,
@@ -547,59 +388,61 @@
"SpeedLimit": 1,
"AliasName": "",
"IsActive": true,
- "RfidId": 37,
+ "RfidId": 91,
"NodeTextForeColor": "Black",
"NodeTextFontSize": 7.0,
- "ID2": "0037(*N027)",
+ "ID2": "0091(*N027)",
"Id": "N027",
"Type": 0,
- "Position": "-114, 625"
+ "Position": "-211, 632"
},
{
- "Text": "",
- "StationType": 7,
- "CanDocking": false,
- "DockDirection": 0,
+ "Text": "Buffer5",
+ "StationType": 4,
+ "CanDocking": true,
+ "DockDirection": 2,
"MagnetDirections": {},
"ConnectedNodes": [
- "N001"
+ "N021",
+ "N029"
],
"CanTurnLeft": true,
"CanTurnRight": true,
"DisableCross": false,
"SpeedLimit": 1,
- "AliasName": "",
+ "AliasName": "BUFFER5",
"IsActive": true,
- "RfidId": 39,
+ "RfidId": 35,
"NodeTextForeColor": "Black",
"NodeTextFontSize": 7.0,
- "ID2": "0039(*N028)",
+ "ID2": "0035(*N028)",
"Id": "N028",
"Type": 0,
- "Position": "225, 269"
+ "Position": "-59, 629"
},
{
- "Text": "",
- "StationType": 7,
- "CanDocking": false,
- "DockDirection": 0,
+ "Text": "Buffer6",
+ "StationType": 4,
+ "CanDocking": true,
+ "DockDirection": 2,
"MagnetDirections": {},
"ConnectedNodes": [
- "N014"
+ "N028",
+ "N027"
],
"CanTurnLeft": true,
"CanTurnRight": true,
"DisableCross": false,
"SpeedLimit": 1,
- "AliasName": "",
+ "AliasName": "BUFFER6",
"IsActive": true,
- "RfidId": 38,
+ "RfidId": 36,
"NodeTextForeColor": "Black",
"NodeTextFontSize": 7.0,
- "ID2": "0038(*N029)",
+ "ID2": "0036(*N029)",
"Id": "N029",
"Type": 0,
- "Position": "519, 720"
+ "Position": "-133, 629"
},
{
"Text": "",
@@ -607,56 +450,30 @@
"CanDocking": false,
"DockDirection": 0,
"MagnetDirections": {},
- "ConnectedNodes": [
- "N010"
- ],
+ "ConnectedNodes": [],
"CanTurnLeft": true,
"CanTurnRight": true,
"DisableCross": false,
"SpeedLimit": 1,
"AliasName": "",
"IsActive": true,
- "RfidId": 0,
+ "RfidId": 90,
"NodeTextForeColor": "Black",
"NodeTextFontSize": 7.0,
- "ID2": "(*N030)",
+ "ID2": "0090(*N030)",
"Id": "N030",
"Type": 0,
- "Position": "246, 447"
- }
- ],
- "Labels": [
- {
- "Text": "Amkor Technology Korea",
- "ForeColor": "White",
- "BackColor": "MidnightBlue",
- "FontFamily": "Arial",
- "FontSize": 20.0,
- "FontStyle": 0,
- "Padding": 5,
- "Id": "LBL001",
- "Type": 1,
- "Position": "180, 105"
- }
- ],
- "Images": [
- {
- "Name": "Image",
- "ImagePath": "",
- "ImageBase64": "",
- "Scale": "1, 1",
- "Opacity": 1.0,
- "Rotation": 0.0,
- "Id": "IMG001",
- "Type": 2,
- "Position": "633, 310"
+ "Position": "435, 349"
}
],
+ "Labels": [],
+ "Images": [],
"Marks": [
{
"X": 520.0,
"Y": 690.0,
"Rotation": -178.01940688369234,
+ "Length": 0.0,
"Id": "2cb51787-c8cf-4ddb-97f0-b71f519d47dc",
"Type": 3,
"Position": "520, 690"
@@ -665,6 +482,7 @@
"X": -74.0,
"Y": 624.0,
"Rotation": 90.0,
+ "Length": 0.0,
"Id": "f704ebe0-1653-4559-b06f-1eaecafbefba",
"Type": 3,
"Position": "-74, 624"
@@ -673,6 +491,7 @@
"X": 12.0,
"Y": 625.0,
"Rotation": 90.0,
+ "Length": 0.0,
"Id": "d5b27365-79a2-4351-84c3-6767941ec0be",
"Type": 3,
"Position": "12, 625"
@@ -681,6 +500,7 @@
"X": 91.0,
"Y": 625.0,
"Rotation": 89.2872271068898,
+ "Length": 0.0,
"Id": "0367cafb-9f85-4440-b6b4-c802a58e6181",
"Type": 3,
"Position": "91, 625"
@@ -689,6 +509,7 @@
"X": 183.0,
"Y": 622.0,
"Rotation": 88.405167720722616,
+ "Length": 0.0,
"Id": "1f4ab2c9-07f8-4675-802d-9b4824b55198",
"Type": 3,
"Position": "183, 622"
@@ -697,6 +518,7 @@
"X": 275.0,
"Y": 269.0,
"Rotation": 91.712220129051758,
+ "Length": 0.0,
"Id": "15fddfa4-ff74-48ff-b922-4aacdce1960b",
"Type": 3,
"Position": "275, 269"
@@ -705,6 +527,7 @@
"X": 89.0,
"Y": 697.0,
"Rotation": 0.38243447796178032,
+ "Length": 0.0,
"Id": "4b699847-36d4-471c-b990-4ad37967c2dc",
"Type": 3,
"Position": "89, 697"
@@ -713,6 +536,7 @@
"X": 183.0,
"Y": 699.0,
"Rotation": -1.3380194104322385,
+ "Length": 0.0,
"Id": "a9f68317-f1c2-47d8-b029-348b5428be9f",
"Type": 3,
"Position": "183, 699"
@@ -721,6 +545,7 @@
"X": 9.0,
"Y": 699.0,
"Rotation": 0.84311038333069632,
+ "Length": 0.0,
"Id": "fe227205-2a65-4ba9-bb4a-4efb4ed0a7b0",
"Type": 3,
"Position": "9, 699"
@@ -729,6 +554,7 @@
"X": -74.0,
"Y": 697.0,
"Rotation": 1.659829660758831,
+ "Length": 0.0,
"Id": "5dd29191-798c-480c-b066-7947bfcc4fb7",
"Type": 3,
"Position": "-74, 697"
@@ -737,22 +563,25 @@
"X": -71.0,
"Y": 596.0,
"Rotation": 0.0,
+ "Length": 0.0,
"Id": "649729f0-ff04-4e11-8869-f6a39d815427",
"Type": 3,
"Position": "-71, 596"
},
{
- "X": 10.0,
- "Y": 601.0,
+ "X": 36.0,
+ "Y": 600.0,
"Rotation": 0.0,
+ "Length": 0.0,
"Id": "2bb9a821-f86b-4190-a182-64abe2c940ed",
"Type": 3,
- "Position": "10, 601"
+ "Position": "36, 600"
},
{
"X": 91.0,
"Y": 598.0,
"Rotation": 0.0,
+ "Length": 0.0,
"Id": "821598e1-091a-4884-96fe-6ed5f43c4f62",
"Type": 3,
"Position": "91, 598"
@@ -761,6 +590,7 @@
"X": 184.0,
"Y": 596.0,
"Rotation": 0.0,
+ "Length": 0.0,
"Id": "66c1bbee-89a8-45a9-b585-ddfd59768f6b",
"Type": 3,
"Position": "184, 596"
@@ -769,6 +599,7 @@
"X": 381.0,
"Y": 355.0,
"Rotation": 91.245364266768377,
+ "Length": 0.0,
"Id": "06a10f46-bda8-4b0f-9e7a-63d66bd2f7e4",
"Type": 3,
"Position": "381, 355"
@@ -777,6 +608,7 @@
"X": 519.0,
"Y": 550.0,
"Rotation": 0.0,
+ "Length": 0.0,
"Id": "835b8982-042b-4e2e-a83b-19b32e55cd5b",
"Type": 3,
"Position": "519, 550"
@@ -785,12 +617,12 @@
"Magnets": [
{
"P1": {
- "X": 358.53781512605048,
- "Y": 628.438429217841
+ "X": 438.0,
+ "Y": 623.0
},
"P2": {
- "X": -119.57759581805529,
- "Y": 626.78449598889756
+ "X": -216.0,
+ "Y": 628.0
},
"ControlPoint": null,
"Id": "5a0edec2-7ac3-4c99-bbb4-8debde0c1d07",
@@ -798,73 +630,8 @@
},
{
"P1": {
- "X": -75.0847526191485,
- "Y": 716.14155614369508
- },
- "P2": {
- "X": -73.1298113651053,
- "Y": 561.63119233707459
- },
- "ControlPoint": null,
- "Id": "def7c4b9-86db-42eb-aae6-0c6c9bedcc30",
- "Type": 4
- },
- {
- "P1": {
- "X": 12.69302515862924,
- "Y": 717.25266725480617
- },
- "P2": {
- "X": 11.870188634894689,
- "Y": 560.25023995612207
- },
- "ControlPoint": null,
- "Id": "624327ee-be0f-4373-b60a-786a93c1eabf",
- "Type": 4
- },
- {
- "P1": {
- "X": 90.470802936406983,
- "Y": 716.14155614369508
- },
- "P2": {
- "X": 89.727331492037507,
- "Y": 560.91690662278882
- },
- "ControlPoint": null,
- "Id": "f1e885ae-55f7-42e9-b3aa-648541e97da0",
- "Type": 4
- },
- {
- "P1": {
- "X": 185.470802936407,
- "Y": 725.03044503258388
- },
- "P2": {
- "X": 181.87018863489462,
- "Y": 563.059763765646
- },
- "ControlPoint": null,
- "Id": "dc3e8061-2c99-4f24-ac9b-4020dd91fa8b",
- "Type": 4
- },
- {
- "P1": {
- "X": 343.98784548784573,
- "Y": 353.92216117216128
- },
- "P2": {
- "X": 472.59413991107186,
- "Y": 353.73144759338567
- },
- "ControlPoint": null,
- "Id": "f4c97a5a-2c2c-4b5e-9dd5-332b1670b827",
- "Type": 4
- },
- {
- "P1": {
- "X": 519.32722832722823,
- "Y": 720.25490196078408
+ "X": 520.0,
+ "Y": 565.0
},
"P2": {
"X": 516.16556848250036,
@@ -876,12 +643,12 @@
},
{
"P1": {
- "X": 249.62404756406329,
- "Y": 449.77059623383167
+ "X": 468.0,
+ "Y": 504.0
},
"P2": {
- "X": 518.08558602560174,
- "Y": 452.84751931075476
+ "X": 332.0,
+ "Y": 508.0
},
"ControlPoint": null,
"Id": "0bbb27a4-2355-4294-9f2d-a40e4d3d2930",
@@ -889,11 +656,11 @@
},
{
"P1": {
- "X": 225.77789371790945,
- "Y": 271.30905777229322
+ "X": 371.0,
+ "Y": 270.0
},
"P2": {
- "X": 463.66556848250042,
+ "X": 468.66556848250042,
"Y": 269.44573330767145
},
"ControlPoint": null,
@@ -918,111 +685,41 @@
},
{
"P1": {
- "X": 473.41452991452985,
- "Y": 353.032679738562
+ "X": 454.0,
+ "Y": 504.0
},
"P2": {
- "X": 515.63675213675208,
- "Y": 399.14379084967311
- },
- "ControlPoint": {
- "X": 521.74786324786317,
- "Y": 351.3660130718954
- },
- "Id": "0650b2cb-57f9-44ec-9787-fab878cf2b47",
- "Type": 4
- },
- {
- "P1": {
- "X": 465.08119658119654,
- "Y": 450.2549019607842
- },
- "P2": {
- "X": 518.24918584253533,
- "Y": 519.05971509141114
- },
- "ControlPoint": {
- "X": 522.85897435897425,
- "Y": 450.8104575163398
- },
- "Id": "7007db10-b61b-4726-9775-417951454ddf",
- "Type": 4
- },
- {
- "P1": {
- "X": 473.30842562535759,
- "Y": 351.58859045052856
- },
- "P2": {
- "X": 515.4512827682147,
- "Y": 309.80287616481428
- },
- "ControlPoint": {
- "X": 519.02271133964325,
- "Y": 358.01716187909994
- },
- "Id": "4ef4bfd0-8fc4-48a5-a490-92b35c7fd1c3",
- "Type": 4
- },
- {
- "P1": {
- "X": 464.73699705392903,
- "Y": 450.51716187909989
- },
- "P2": {
- "X": 516.52271133964325,
- "Y": 402.66001902195711
- },
- "ControlPoint": {
- "X": 516.16556848250036,
- "Y": 454.44573330767133
- },
- "Id": "7d18ae7e-7926-4cf4-8dd6-861462e31352",
- "Type": 4
- },
- {
- "P1": {
- "X": 399.76697627462613,
- "Y": 521.72108802571984
- },
- "P2": {
- "X": 462.61739821419411,
- "Y": 449.66152357736206
- },
- "ControlPoint": {
- "X": 391.99239821419411,
- "Y": 447.16152357736206
- },
- "Id": "532be14d-170e-45c5-adcf-0d555b83b010",
- "Type": 4
- },
- {
- "P1": {
- "X": 399.05269056034041,
- "Y": 523.50680231143417
- },
- "P2": {
- "X": 400.11132581222392,
- "Y": 580.622765294022
+ "X": 517.0,
+ "Y": 434.0
},
"ControlPoint": null,
- "Id": "086955e0-0542-4ab5-9ccf-8880e749722a",
+ "Id": "N032",
"Type": 4
},
{
"P1": {
- "X": 353.86132581222392,
- "Y": 629.37276529402186
+ "X": 434.0,
+ "Y": 624.0
},
"P2": {
- "X": 400.11132581222392,
- "Y": 576.872765294022
+ "X": 437.0,
+ "Y": 506.0
},
- "ControlPoint": {
- "X": 404.48632581222392,
- "Y": 630.62276529402186
+ "ControlPoint": null,
+ "Id": "N031",
+ "Type": 4
+ },
+ {
+ "P1": {
+ "X": 436.0,
+ "Y": 508.0
},
- "Id": "2ac7d720-a6df-4174-be74-15ddfe96459b",
+ "P2": {
+ "X": 438.0,
+ "Y": 352.0
+ },
+ "ControlPoint": null,
+ "Id": "N030",
"Type": 4
}
],
@@ -1030,6 +727,6 @@
"BackgroundColorArgb": -14671840,
"ShowGrid": false
},
- "CreatedDate": "2026-01-20T10:36:03.7843912+09:00",
+ "CreatedDate": "2026-02-10T12:53:40.5602334+09:00",
"Version": "1.3"
}
\ No newline at end of file