private void DrawHoles(ImageGraphics ig) { if (holes == null) { return; } var ptDisp1 = new Point(0, 0); var ptDisp2 = (Point)pbxDraw.ClientSize; var ptImg1 = pbxDraw.DispToImg(ptDisp1); var ptImg2 = pbxDraw.DispToImg(ptDisp2); float imgX1 = (float)Math.Floor(ptImg1.X); float imgY1 = (float)Math.Floor(ptImg1.Y); float imgX2 = (float)Math.Floor(ptImg2.X); float imgY2 = (float)Math.Floor(ptImg2.Y); double zoomFactor = pbxDraw.GetZoomFactor(); skipDrawHoleInfo = zoomFactor < 0.5; Pen linePen = Pens.Red; Brush infoBrush = Brushes.Yellow; Font infoFont = SystemFonts.DefaultFont; float holePitch = 32.0f; bool holeDrawCircle = zoomFactor > (4.0 / holePitch); HoleInfoItemType infoItemType = HoleInfoItemType.None; if (rdoHoleInfoIndexX.Checked) { infoItemType = HoleInfoItemType.IndexX; } else if (rdoHoleInfoIndexY.Checked) { infoItemType = HoleInfoItemType.IndexY; } else if (rdoHoleInfoFWD.Checked) { infoItemType = HoleInfoItemType.Fwd; } // 쿼드트리 사용하여 비저블 역역에 포함되는 노드만 그림 DrawNodeHole(tree.root, imgX1, imgY1, imgX2, imgY2, ig, zoomFactor, holeDrawCircle, linePen, infoItemType, infoFont, infoBrush); if (chkDrawCursorHole.Checked && cursorHole != null) { DrawHole(ig, cursorHole, holeDrawCircle, Pens.Lime, infoItemType, infoFont, infoBrush); } }
// 홀그리기 private void DrawHole(ImageGraphics ig, Hole hole, bool holeDrawCircle, Pen linePen, HoleInfoItemType infoItemType, Font infoFont, Brush infoBrush) { if (holeDrawCircle) { DrawHoleCircle(ig, hole, linePen); } else { DrawHolePoint(ig, hole, linePen); } if (infoItemType == HoleInfoItemType.None || skipDrawHoleInfo) { return; } string infoText; if (infoItemType == HoleInfoItemType.IndexX) { infoText = hole.idxX.ToString(); } else if (infoItemType == HoleInfoItemType.IndexY) { infoText = hole.idxY.ToString(); } else { infoText = hole.fwd.ToString(); } DrawHoleInfo(ig, hole, infoText, infoFont, infoBrush); }
// 노드 홀 그리기 private void DrawNodeHole(QuadTreeNode node, float imgX1, float imgY1, float imgX2, float imgY2, ImageGraphics ig, double zoomFactor, bool holeDrawCircle, Pen linePen, HoleInfoItemType infoItemType, Font infoFont, Brush infoBrush) { // 뷰 영역에 벗어난 노드는 리턴 if (node.x1 > imgX2 || node.y1 > imgY2 || node.x2 < imgX1 || node.y2 < imgY1) { return; } // 현재 레벨에서 드로우 if ((node.x2 - node.x1) * zoomFactor <= 8.0) { DrawHole(ig, node.holeFront, holeDrawCircle, linePen, infoItemType, infoFont, infoBrush); return; } // 노드가 리프 노드 이면 노드에 포함된 홀 그리고 리턴 if (node.holes != null) { foreach (Hole hole in node.holes) { DrawHole(ig, hole, holeDrawCircle, linePen, infoItemType, infoFont, infoBrush); } return; } // 하위 노드로 내려감 if (node.childLT != null) { DrawNodeHole(node.childLT, imgX1, imgY1, imgX2, imgY2, ig, zoomFactor, holeDrawCircle, linePen, infoItemType, infoFont, infoBrush); } if (node.childRT != null) { DrawNodeHole(node.childRT, imgX1, imgY1, imgX2, imgY2, ig, zoomFactor, holeDrawCircle, linePen, infoItemType, infoFont, infoBrush); } if (node.childLB != null) { DrawNodeHole(node.childLB, imgX1, imgY1, imgX2, imgY2, ig, zoomFactor, holeDrawCircle, linePen, infoItemType, infoFont, infoBrush); } if (node.childRB != null) { DrawNodeHole(node.childRB, imgX1, imgY1, imgX2, imgY2, ig, zoomFactor, holeDrawCircle, linePen, infoItemType, infoFont, infoBrush); } }