This commit is contained in:
backuppc
2026-01-15 17:34:17 +09:00
parent 64ff2ecfb9
commit ddf111c69f
6 changed files with 232 additions and 81 deletions

View File

@@ -72,6 +72,9 @@ namespace AGVNavigationCore.Controls
DrawDragGhost(g);
}
// 마그넷 방향 텍스트 그리기 (노드 위에 표시)
DrawMagnetDirections(g);
// AGV 그리기
DrawAGVs(g);
@@ -105,6 +108,105 @@ namespace AGVNavigationCore.Controls
}
private void DrawMagnetDirections(Graphics g)
{
if (_nodes == null) return;
using (var font = new Font("Arial", 8, FontStyle.Bold))
using (var brushS = new SolidBrush(Color.Magenta))
using (var brushL = new SolidBrush(Color.Green))
using (var brushR = new SolidBrush(Color.Blue))
using (var brushBg = new SolidBrush(Color.FromArgb(180, 255, 255, 255)))
{
foreach (var node in _nodes)
{
if (node.MagnetDirections != null && node.MagnetDirections.Count > 0)
{
foreach (var kvp in node.MagnetDirections)
{
var targetId = kvp.Key;
var dir = kvp.Value;
var targetNode = _nodes.FirstOrDefault(n => n.Id == targetId);
if (targetNode != null)
{
// 방향 텍스트 위치 계산 (출발 -> 도착 벡터의 일정 거리 지점)
var start = node.Position;
var end = targetNode.Position;
var angle = Math.Atan2(end.Y - start.Y, end.X - start.X);
// 박스(텍스트) 중심 위치: 약 40px 거리
var boxDist = 40;
var boxX = start.X + boxDist * Math.Cos(angle);
var boxY = start.Y + boxDist * Math.Sin(angle);
string text = dir.ToString();
Color color = Color.Blue;
if (dir == MagnetPosition.L) color = Color.LimeGreen;
else if (dir == MagnetPosition.R) color = Color.Red;
// 화살표 및 텍스트 설정
using (var arrowBrush = new SolidBrush(color))
using (var arrowPen = new Pen(color, 2)) // 두께 약간 증가
using (var textBrush = new SolidBrush(color))
{
// 1. 화살표 그리기 (박스를 가로지르는 선)
// 시작점: 노드 근처 (25px)
// 끝점: 박스 너머 (55px)
var arrowStartDist = 25;
var arrowEndDist = 55;
var pStart = new PointF((float)(start.X + arrowStartDist * Math.Cos(angle)), (float)(start.Y + arrowStartDist * Math.Sin(angle)));
var pEnd = new PointF((float)(start.X + arrowEndDist * Math.Cos(angle)), (float)(start.Y + arrowEndDist * Math.Sin(angle)));
// 화살표 선 그리기
g.DrawLine(arrowPen, pStart, pEnd);
// 화살표 머리 그리기 (끝점에)
var arrowSize = 6;
var pHead1 = new PointF((float)(pEnd.X + arrowSize * Math.Cos(angle)), (float)(pEnd.Y + arrowSize * Math.Sin(angle))); // 뾰족한 끝
// 삼각형 머리 (채우기)
var pBackL = new PointF((float)(pEnd.X + arrowSize * Math.Cos(angle + 2.5)), (float)(pEnd.Y + arrowSize * Math.Sin(angle + 2.5)));
var pBackR = new PointF((float)(pEnd.X + arrowSize * Math.Cos(angle - 2.5)), (float)(pEnd.Y + arrowSize * Math.Sin(angle - 2.5)));
// pHead1이 가장 먼 쪽이 되도록 조정 (pEnd가 삼각형의 뒷부분 중심이 되도록)
// pEnd에서 시작해서 앞으로 나가는 삼각형
// pTip = pEnd + size * angle
// pBackL = pEnd + size/2 * angle_back_L (약간 뒤로)
// 현재 코드는 pEnd를 중심으로, pHead1이 앞, pBackL/R이 뒤... 가 아니라
// pHead1, pBackK, pBackR로 삼각형을 그림.
// pHead1이 팁.
g.FillPolygon(arrowBrush, new PointF[] { pHead1, pBackL, pBackR });
// 2. 텍스트 그리기 (화살표 위에 박스, 그 위에 텍스트)
var textSize = g.MeasureString(text, font);
var textPoint = new PointF((float)(boxX - textSize.Width / 2), (float)(boxY - textSize.Height / 2));
//편집모드에서만 글자를 표시한다.
if(Mode == CanvasMode.Edit)
{
// 텍스트 배경 (반투명 - 선이 은은하게 보이도록 투명도 조절하거나, 가독성을 위해 불투명하게 처리)
// 사용자가 "박스를 가로지르는" 느낌을 원했으므로 선이 보여야 함. 하지만 텍스트 가독성도 필요.
// 배경을 아주 옅게 (Alpha 100정도) 처리하여 선이 보이게 함.
using (var translucentBg = new SolidBrush(Color.FromArgb(120, 255, 255, 255)))
{
g.FillRectangle(translucentBg, textPoint.X - 1, textPoint.Y - 1, textSize.Width + 2, textSize.Height + 2);
}
g.DrawString(text, font, textBrush, textPoint);
}
}
}
}
}
}
}
}
void DrawAlertMessage(Graphics g)
{
if (showalert == false) return;

View File

@@ -157,31 +157,20 @@ namespace AGVNavigationCore.PathFinding.Planning
//갈림길에 있다면 미리 방향을 저장해준다.
if ((node.ConnectedNodes?.Count ?? 0) > 2 && nextNode != null)
{
switch (node.RfidId)
//다음 노드ID를 확인해서 마그넷 방향 데이터를 찾는다.
if (node.MagnetDirections.ContainsKey(nextNode.Id) == false)
{
case 6:
if (nextNode.RfidId == 7)
magnetDirection = MagnetDirection.Left;
else if (nextNode.RfidId == 13)
magnetDirection = MagnetDirection.Right;
else
return AGVPathResult.CreateFailure($"{node.ID2}->{nextNode.ID2} 의 (목표)갈림길 방향이 입력되지 않았습니다", 0, 0);
break;
case 7:
if (nextNode.RfidId == 6)
magnetDirection = MagnetDirection.Right;
else
return AGVPathResult.CreateFailure( $"{node.ID2}->{nextNode.ID2} 의 (목표)갈림길 방향이 입력되지 않았습니다", 0, 0);
break;
case 13:
if (nextNode.RfidId == 6)
magnetDirection = MagnetDirection.Left;
else
return AGVPathResult.CreateFailure( $"{node.ID2}->{nextNode.ID2} 의 (목표)갈림길 방향이 입력되지 않았습니다", 0, 0);
break;
default:
return AGVPathResult.CreateFailure( $"{node.ID2}->{nextNode.ID2} 의 (시작)갈림길 방향이 입력되지 않았습니다", 0, 0);
return AGVPathResult.CreateFailure($"{node.ID2}->{nextNode.ID2} 의 (목표)갈림길 방향이 입력되지 않았습니다", 0, 0);
}
else
{
var magdir = node.MagnetDirections[nextNode.Id].ToString();
if (magdir == "L") magnetDirection = MagnetDirection.Left;
else if (magdir == "R") magnetDirection = MagnetDirection.Right;
}
}
var nodeInfo = new NodeMotorInfo(i + 1, node.Id, node.RfidId, prevDirection, nextNode, magnetDirection);