private static void GetPolygonLevel4GridIndex(List <GridIndex> result, GridSegment region, IList <GridPoint> gridPoints, IEnumerable <GridSegment> segments) { var beginX = Math.Floor(region.X1 / GridConfig.Level4XCellSpan) * GridConfig.Level4XCellSpan; var beginY = Math.Floor(region.Y1 / GridConfig.Level4YCellSpan) * GridConfig.Level4YCellSpan; var endX = Math.Floor(region.X2 / GridConfig.Level4XCellSpan) * GridConfig.Level4XCellSpan; var endY = Math.Floor(region.Y2 / GridConfig.Level4YCellSpan) * GridConfig.Level4YCellSpan; var row = (int)Math.Round((endY - beginY) / GridConfig.Level4YCellSpan) + 1; var column = (int)Math.Round((endX - beginX) / GridConfig.Level4XCellSpan) + 1; if (beginX == endX && beginY == endY) { // 只占用四级一个格子,无需再分 var point = new GridPoint(beginX, beginY); result.Add(GetPointGridIndex(point)); } else { for (int i = 0; i < column; i++) { var x = beginX + i * GridConfig.Level4XCellSpan; for (int j = 0; j < row; j++) { var y = beginY + j * GridConfig.Level4YCellSpan; var gridRect = new GridRect(x, y, GridConfig.Level4XCellSpan, GridConfig.Level4YCellSpan); var point = new GridPoint(x + 0.5d * GridConfig.Level4XCellSpan, y + 0.5d * GridConfig.Level4YCellSpan); if (gridPoints.Any(p => RelationPointAndRect(p, gridRect) == GridRelationShip.Within)) { result.Add(GetPointGridIndex(point)); } else { var relationship = RelationRectAndPanel(gridRect, segments); if (relationship != GridRelationShip.None) { if (relationship == GridRelationShip.Within) { } result.Add(GetPointGridIndex(point)); } } } } } }
private static GridRelationShip RelationPointAndPanel(GridPoint point, IEnumerable <GridSegment> segments) { var xArray = GetScaleX(point, segments.Where(s => PointContain(point.Y, s.Y1, s.Y2))).OrderBy(x => x); var flag = true; foreach (var x in xArray) { if (point.X == x) { return(GridRelationShip.Intersect); } else if (point.X < x) { return(flag ? GridRelationShip.None : GridRelationShip.Within); } flag = !flag; } return(GridRelationShip.None); }
private static IEnumerable <GridIndex> GetLineGridIndex(GridPoint startPositioning, GridPoint endPositioning) { // 一次函数公式: kx + b = y var k = (startPositioning.Y - endPositioning.Y) / (startPositioning.X - endPositioning.X); var b = startPositioning.Y - k * startPositioning.X; if (!double.IsInfinity(k)) { var maxColumn = (int)Math.Floor(Math.Max(startPositioning.X, endPositioning.X) / GridConfig.Level4XCellSpan); var minColumn = (int)Math.Ceiling(Math.Min(startPositioning.X, endPositioning.X) / GridConfig.Level4XCellSpan); for (int column = minColumn; column <= maxColumn; column++) { // 多加 1/2 的值是为了 避免 刚好在边界点因为小数点误差而计算错误 var x = (column + 0.00001d) * GridConfig.Level4XCellSpan; var y = k * x + b; yield return(GetPointGridIndex(new GridPoint(x, y))); yield return(GetPointGridIndex(new GridPoint(x - GridConfig.Level4XCellSpan, y))); } } if (k != 0) { var maxRow = (int)Math.Floor((Math.Max(startPositioning.Y, endPositioning.Y) / GridConfig.Level4YCellSpan)); var minRow = (int)Math.Ceiling(Math.Min(startPositioning.Y, endPositioning.Y) / GridConfig.Level4YCellSpan); var isInfinity = double.IsInfinity(k); for (int row = minRow; row <= maxRow; row++) { // 多加 1/2 的值是为了 避免 刚好在边界点因为小数点误差而计算错误 var y = (row + 0.00001d) * GridConfig.Level4YCellSpan; var x = isInfinity ? endPositioning.X : ((y - b) / k); yield return(GetPointGridIndex(new GridPoint(x, y))); yield return(GetPointGridIndex(new GridPoint(x, y - GridConfig.Level4YCellSpan))); } } yield return(GetPointGridIndex(startPositioning)); yield return(GetPointGridIndex(endPositioning)); }
private void Window_MouseWheel(object sender, MouseWheelEventArgs e) { if (!_isDrawing) { Point point = e.GetPosition(GridCanvas); if (e.Delta > 0 && _level < 4) { _offsetPositioning -= TranformPositioning(point); _level++; _offsetPositioning += TranformPositioning(point); DrawGrid(); GridLevelTextBlock.Text = _level.ToString(); } else if (e.Delta < 0 && _level > 1) { _offsetPositioning -= TranformPositioning(point); _level--; _offsetPositioning += TranformPositioning(point); DrawGrid(); GridLevelTextBlock.Text = _level.ToString(); } } }
private static IEnumerable <double> GetScaleX(GridPoint point, IEnumerable <GridSegment> segments) { foreach (var segment in segments) { if (segment.Y1 == segment.Y2) { if (PointContain(point.X, segment.X1, segment.X2)) { yield return(point.X); yield return(point.X); break; } yield return(segment.X1); yield return(segment.X2); } else { yield return(GetX(point.Y, segment)); } } }
private void DrawLabel(int xFlag1, int yFlag1, int xFlag2, int yFlag2, int levelXGrid, int levelYGrid) { double cellWidth = WIDTH * xFlag1 / levelXGrid; double cellHeight = HEIGHT * yFlag1 / levelYGrid; double offsetX = _offsetPositioning.X * WIDTH * xFlag1 * xFlag2 / GridConfig.XSpan; double offsetY = _offsetPositioning.Y * HEIGHT * yFlag1 * yFlag2 / GridConfig.YSpan; double beginX = offsetX % cellWidth; double beginY = offsetY % cellHeight; GridPoint gridPoint = new GridPoint(); for (int row = -1; row <= levelYGrid + 1; row++) { double y = row * cellHeight + beginY; for (int col = -1; col < levelXGrid + 1; col++) { var brush = Brushes.White; double x = col * cellWidth + beginX; // 多加 1/2 的值是为了 避免 刚好在边界点因为小数点误差而计算错误 gridPoint = TranformPositioning(x - offsetX + cellWidth / 2d, y - offsetY + cellHeight / 2d); if (gridPoint.Y > 0d && gridPoint.X > 0d && gridPoint.Y < GridConfig.YSpan && gridPoint.X < GridConfig.XSpan) { StackPanel stackPanel = new StackPanel(); stackPanel.Orientation = Orientation.Horizontal; stackPanel.VerticalAlignment = VerticalAlignment.Center; stackPanel.HorizontalAlignment = HorizontalAlignment.Center; stackPanel.Children.Add(new TextBlock() { Text = "(" }); int lv1Index = gridPoint.TranformGridIndex(GridConfig.LEVEL1_X_GRID, GridConfig.LEVEL1_Y_GRID, GridConfig.Level1XCellSpan, GridConfig.Level1YCellSpan); stackPanel.Children.Add(new TextBlock() { Text = lv1Index.ToString(), Foreground = _level1Brush }); if (_level > 1) { int lv2Index = gridPoint.TranformGridIndex(GridConfig.LEVEL2_X_GRID, GridConfig.LEVEL2_Y_GRID, GridConfig.Level2XCellSpan, GridConfig.Level2YCellSpan); stackPanel.Children.Add(new TextBlock() { Text = ", " }); stackPanel.Children.Add(new TextBlock() { Text = lv2Index.ToString(), Foreground = _level2Brush }); if (_level > 2) { int lv3Index = gridPoint.TranformGridIndex(GridConfig.LEVEL3_X_GRID, GridConfig.LEVEL3_Y_GRID, GridConfig.Level3XCellSpan, GridConfig.Level3YCellSpan); stackPanel.Children.Add(new TextBlock() { Text = ", " }); stackPanel.Children.Add(new TextBlock() { Text = lv3Index.ToString(), Foreground = _level3Brush }); if (_level > 3) { int lv4Index = gridPoint.TranformGridIndex(GridConfig.LEVEL4_X_GRID, GridConfig.LEVEL4_Y_GRID, GridConfig.Level4XCellSpan, GridConfig.Level4YCellSpan); stackPanel.Children.Add(new TextBlock() { Text = ", " }); stackPanel.Children.Add(new TextBlock() { Text = lv4Index.ToString(), Foreground = _level4Brush }); if (_gridIndexes.Any(g => g.Index1 == lv1Index && g.Index2 == lv2Index && g.Index3 == lv3Index && g.Index4 == lv4Index)) { brush = _level4Brush; } else if (_gridIndexes.Any(g => g.Index1 == lv1Index && g.Index2 == lv2Index && g.Index3 == lv3Index && !g.Index4.HasValue)) { brush = _level3Brush; } else if (_gridIndexes.Any(g => g.Index1 == lv1Index && g.Index2 == lv2Index && !g.Index3.HasValue)) { brush = _level2Brush; } else if (_gridIndexes.Any(g => g.Index1 == lv1Index && !g.Index2.HasValue)) { brush = _level1Brush; } } else if (_gridIndexes.Any(g => g.Index1 == lv1Index && g.Index2 == lv2Index && g.Index3 == lv3Index)) { brush = _level3Brush; } else if (_gridIndexes.Any(g => g.Index1 == lv1Index && g.Index2 == lv2Index && !g.Index3.HasValue)) { brush = _level2Brush; } else if (_gridIndexes.Any(g => g.Index1 == lv1Index && !g.Index2.HasValue)) { brush = _level1Brush; } } else if (_gridIndexes.Any(g => g.Index1 == lv1Index && g.Index2 == lv2Index)) { brush = _level2Brush; } else if (_gridIndexes.Any(g => g.Index1 == lv1Index && !g.Index2.HasValue)) { brush = _level1Brush; } } else if (_gridIndexes.Any(g => g.Index1 == lv1Index)) { brush = _level1Brush; } stackPanel.Children.Add(new TextBlock() { Text = ")" }); Grid grid = new Grid(); grid.Children.Add(new Rectangle() { Opacity = brush != Brushes.White ? 0.3d : 1d, Fill = brush }); grid.Children.Add(stackPanel); grid.Height = cellHeight; grid.Width = cellWidth; grid.SetValue(Canvas.LeftProperty, x); grid.SetValue(Canvas.TopProperty, y); GridCanvas.Children.Add(grid); } } } }
public GridSegment(GridPoint gridPoint1, GridPoint gridPoint2) { _point1 = gridPoint1; _point2 = gridPoint2; }
private static double CrossMul(GridPoint point1, GridPoint point2) { return(point1.X * point2.Y - point1.Y * point2.X); }
private static GridPoint GetVector(GridPoint point1, GridPoint point2) { return(new GridPoint(point1.X - point2.X, point1.Y - point2.Y)); }
private static void GetPolygonLevel3GridIndex(List <GridIndex> result, GridSegment region, IList <GridPoint> gridPoints, IEnumerable <GridSegment> segments) { var beginX = Math.Floor(region.X1 / GridConfig.Level3XCellSpan) * GridConfig.Level3XCellSpan; var beginY = Math.Floor(region.Y1 / GridConfig.Level3YCellSpan) * GridConfig.Level3YCellSpan; var endX = Math.Floor(region.X2 / GridConfig.Level3XCellSpan) * GridConfig.Level3XCellSpan; var endY = Math.Floor(region.Y2 / GridConfig.Level3YCellSpan) * GridConfig.Level3YCellSpan; var row = (int)Math.Round((endY - beginY) / GridConfig.Level3YCellSpan) + 1; var column = (int)Math.Round((endX - beginX) / GridConfig.Level3XCellSpan) + 1; if (beginX == endX && beginY == endY) { // 只占用三级一个格子 GetPolygonLevel4GridIndex(result, region, gridPoints, segments); } else { for (int i = 0; i < column; i++) { var x = beginX + i * GridConfig.Level3XCellSpan; for (int j = 0; j < row; j++) { var y = beginY + j * GridConfig.Level3YCellSpan; var gridRect = new GridRect(x, y, GridConfig.Level3XCellSpan, GridConfig.Level3YCellSpan); if (gridPoints.Any(p => RelationPointAndRect(p, gridRect) == GridRelationShip.Within)) { // 多边形顶点所在的格子 // 不能压到边界,否则会判断过界,所以边界需要退一点 // Intersect GetPolygonLevel4GridIndex(result, new GridSegment(gridRect.Point1.X, gridRect.Point1.Y, gridRect.Point4.X - 0.5d * GridConfig.Level4XCellSpan, gridRect.Point4.Y - 0.5d * GridConfig.Level4YCellSpan), gridPoints, segments); } else { var relationship = RelationRectAndPanel(gridRect, segments); if (relationship == GridRelationShip.Within) { // 多边形背部完全包含的三级格子,无需再分 // Within var point = new GridPoint(x + 0.5d * GridConfig.Level4XCellSpan, y + 0.5d * GridConfig.Level4YCellSpan); result.Add(new GridIndex() { Index1 = point.TranformGridIndex( GridConfig.LEVEL1_X_GRID, GridConfig.LEVEL1_Y_GRID, GridConfig.Level1XCellSpan, GridConfig.Level1YCellSpan), Index2 = point.TranformGridIndex( GridConfig.LEVEL2_X_GRID, GridConfig.LEVEL2_Y_GRID, GridConfig.Level2XCellSpan, GridConfig.Level2YCellSpan), Index3 = point.TranformGridIndex( GridConfig.LEVEL3_X_GRID, GridConfig.LEVEL3_Y_GRID, GridConfig.Level3XCellSpan, GridConfig.Level3YCellSpan), }); } else if (relationship == GridRelationShip.Intersect) { // 多边形与格子相交, 继续再分 // 不能压到边界,否则会判断过界,所以边界需要退一点 // Intersect GetPolygonLevel4GridIndex(result, new GridSegment(gridRect.Point1.X, gridRect.Point1.Y, gridRect.Point4.X - 0.5d * GridConfig.Level4XCellSpan, gridRect.Point4.Y - 0.5d * GridConfig.Level4YCellSpan), gridPoints, segments); } } } } } }