From 41e551fd1d9ad3b1885d1ba8a85d7c24e5e85c20 Mon Sep 17 00:00:00 2001 From: KozlovPS Date: Wed, 27 May 2026 10:36:27 +0300 Subject: [PATCH] =?UTF-8?q?RevitBuildCoordVolumes:=20=D0=98=D1=81=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=B1=D0=BA=D0=B8=20=D1=80=D0=B0=D0=B7=D0=B1=D0=B8=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=BD=D0=B0=20=D0=BA=D0=B2=D0=B0=D0=B4?= =?UTF-8?q?=D1=80=D0=B0=D1=82=D1=8B=20=D0=BF=D1=80=D0=B8=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=B2=D0=BE=D1=80=D0=BE=D1=82=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/SpatialElementDividerService.cs | 57 +++++++++++++------ 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/src/RevitBuildCoordVolumes/Models/Services/SpatialElementDividerService.cs b/src/RevitBuildCoordVolumes/Models/Services/SpatialElementDividerService.cs index 9851aed33..cf1c836d4 100644 --- a/src/RevitBuildCoordVolumes/Models/Services/SpatialElementDividerService.cs +++ b/src/RevitBuildCoordVolumes/Models/Services/SpatialElementDividerService.cs @@ -20,9 +20,9 @@ public SpatialElementDividerService(IContourService contourService) { } public List DivideSpatialElement( - SpatialElement spatialElement, - BuildCoordVolumeSettings settings, - ProgressService progressService) { + SpatialElement spatialElement, + BuildCoordVolumeSettings settings, + ProgressService progressService) { double angleDeg = UnitUtils.ConvertToInternalUnits(settings.SquareAngleDeg, UnitTypeId.Degrees); double side = UnitUtils.ConvertToInternalUnits(settings.SquareSideMm, UnitTypeId.Millimeters); var contour = _contourService.GetOuterContour(spatialElement); @@ -34,21 +34,42 @@ public List DivideSpatialElement( .Select(curve => curve.GetEndPoint(0)) .ToList(); - double minX = contourDots.Min(p => p.X); - double maxX = contourDots.Max(p => p.X); - double minY = contourDots.Min(p => p.Y); - double maxY = contourDots.Max(p => p.Y); - - var origin = new XYZ((minX + maxX) / 2, (minY + maxY) / 2, 0); + // Центр контура + var origin = new XYZ( + contourDots.Average(p => p.X), + contourDots.Average(p => p.Y), + 0); + // Повернутые оси var ux = new XYZ(Math.Cos(angleDeg), Math.Sin(angleDeg), 0); var uy = new XYZ(-Math.Sin(angleDeg), Math.Cos(angleDeg), 0); - double halfWidth = (maxX - minX) / 2; - double halfHeight = (maxY - minY) / 2; + // Габариты в локальной системе координат + var localXs = contourDots + .Select(p => (p - origin).DotProduct(ux)) + .ToList(); + + var localYs = contourDots + .Select(p => (p - origin).DotProduct(uy)) + .ToList(); + + double minLocalX = localXs.Min(); + double maxLocalX = localXs.Max(); + + double minLocalY = localYs.Min(); + double maxLocalY = localYs.Max(); - int nx = (int) (halfWidth / side) + 1; - int ny = (int) (halfHeight / side) + 1; + // нужен запас минимум в диагональ квадрата, + // иначе при повороте угловые квадраты не попадут в диапазон + double extra = side * Math.Sqrt(2); + + int nx = (int) Math.Ceiling( + (Math.Max(Math.Abs(minLocalX), Math.Abs(maxLocalX)) + extra) + / side); + + int ny = (int) Math.Ceiling( + (Math.Max(Math.Abs(minLocalY), Math.Abs(maxLocalY)) + extra) + / side); progressService?.BeginStage(ProgressType.DivideSpatial); int total = (2 * nx + 1) * (2 * ny + 1); @@ -59,13 +80,17 @@ public List DivideSpatialElement( for(int iy = -ny; iy <= ny; iy++) { progressService?.CancellationToken.ThrowIfCancellationRequested(); - var basePoint = origin + ux * (ix * side) + uy * (iy * side); + var basePoint = + origin + + ux * (ix * side) + + uy * (iy * side); var p1 = basePoint; var p2 = basePoint + ux * side; var p3 = basePoint + ux * side + uy * side; var p4 = basePoint + uy * side; + // Проверяем все углы if(!GeometryUtility.IsPointInsidePolygon(p1, contourDots) || !GeometryUtility.IsPointInsidePolygon(p2, contourDots) || !GeometryUtility.IsPointInsidePolygon(p3, contourDots) @@ -75,10 +100,6 @@ public List DivideSpatialElement( var center = (p1 + p3) / 2; - if(!GeometryUtility.IsPointInsidePolygon(center, contourDots)) { - continue; - } - polygons.Add(new PolygonObject { Center = center, Sides = [