Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ public SpatialElementDividerService(IContourService contourService) {
}

public List<PolygonObject> 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);
Expand All @@ -34,21 +34,42 @@ public List<PolygonObject> 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);
Expand All @@ -59,13 +80,17 @@ public List<PolygonObject> 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)
Expand All @@ -75,10 +100,6 @@ public List<PolygonObject> DivideSpatialElement(

var center = (p1 + p3) / 2;

if(!GeometryUtility.IsPointInsidePolygon(center, contourDots)) {
continue;
}

polygons.Add(new PolygonObject {
Center = center,
Sides = [
Expand Down
Loading