From f6abb548c1b13825fbf6b0189a3630e128ba77c6 Mon Sep 17 00:00:00 2001 From: Nils Schmidt Date: Tue, 31 Oct 2023 16:53:25 +0100 Subject: [PATCH] Prepared fix for issue #993. --- .../enumtype/AlignAndDistribute.java | 186 ++++++++++++------ 1 file changed, 127 insertions(+), 59 deletions(-) diff --git a/src/org/nschmidt/ldparteditor/enumtype/AlignAndDistribute.java b/src/org/nschmidt/ldparteditor/enumtype/AlignAndDistribute.java index c515a6357..35caacca2 100644 --- a/src/org/nschmidt/ldparteditor/enumtype/AlignAndDistribute.java +++ b/src/org/nschmidt/ldparteditor/enumtype/AlignAndDistribute.java @@ -17,12 +17,12 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of import java.math.BigDecimal; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.SequencedSet; import java.util.Set; +import java.util.TreeMap; import java.util.TreeSet; import org.nschmidt.ldparteditor.composite.Composite3D; @@ -51,7 +51,7 @@ public static void align(AlignAndDistribute axis) { final List groups = addSnapshotAndPrepareGroupSelection(vm); NLogger.debug(AlignAndDistribute.class, "Identified {0} selected group(s) to align.", groups.size()); //$NON-NLS-1$ if (groups.isEmpty()) return; - calcuateMinMaxAvgForGroups(groups, vm, axis); + calculateMinMaxAvgForGroups(groups, vm, axis); final boolean alignOnX = axis == X_AVG || axis == X_MAX || axis == X_MIN; final boolean alignOnY = axis == Y_AVG || axis == Y_MAX || axis == Y_MIN; final boolean alignOnZ = axis == Z_AVG || axis == Z_MAX || axis == Z_MIN; @@ -120,8 +120,94 @@ public static void distribute(AlignAndDistribute axis) { final List groups = addSnapshotAndPrepareGroupSelection(vm); NLogger.debug(AlignAndDistribute.class, "Identified {0} selected group(s) to distribute.", groups.size()); //$NON-NLS-1$ if (groups.size() <= 2) return; - calcuateMinMaxAvgForGroups(groups, vm, axis); - // FIXME Needs implementation! + calculateMinMaxAvgForGroups(groups, vm, axis); + final boolean distributeOnX = axis == X_AVG || axis == X_MAX || axis == X_MIN; + final boolean distributeOnY = axis == Y_AVG || axis == Y_MAX || axis == Y_MIN; + final boolean distributeOnZ = axis == Z_AVG || axis == Z_MAX || axis == Z_MIN; + final boolean distributeAvg = axis == X_AVG || axis == Y_AVG || axis == Z_AVG; + final boolean distributeMin = axis == X_MIN || axis == Y_MIN || axis == Z_MIN; + final boolean distributeMax = axis == X_MAX || axis == Y_MAX || axis == Z_MAX; + + BigDecimal min; + BigDecimal max; + if (distributeMin) { + min = groups.get(0).min()[0]; + } else if (distributeMax) { + min = groups.get(0).max()[0]; + } else if (distributeAvg) { + min = groups.get(0).avg()[0]; + } else { + min = BigDecimal.ZERO; + } + + max = min; + + for (SelectionGroup group : groups) { + final BigDecimal value; + if (distributeMin) { + value = group.min()[0]; + } else if (distributeMax) { + value = group.max()[0]; + } else if (distributeAvg) { + value = group.avg()[0]; + } else { + value = BigDecimal.ZERO; + } + + if (value.compareTo(min) < 0) { + min = value; + } + if (value.compareTo(max) > 0) { + max = value; + } + } + + final BigDecimal span = max.subtract(min); + final BigDecimal increment = span.divide(BigDecimal.valueOf(groups.size() - 1L), Threshold.MC); + BigDecimal destination = min; + + groups.sort((a, b) -> { + if (distributeAvg) { + return a.avg()[0].compareTo(b.avg()[0]); + } else if (distributeMin) { + return a.min()[0].compareTo(b.min()[0]); + } else if (distributeMax) { + return a.max()[0].compareTo(b.max()[0]); + } else { + return a.avg()[0].compareTo(b.avg()[0]); + } + }); + + for (SelectionGroup group : groups) { + final BigDecimal delta; + if (distributeAvg) { + // source + delta = destination + // delta = destination - source + delta = destination.subtract(group.avg()[0]); + } else if (distributeMin) { + delta = destination.subtract(group.min()[0]); + } else if (distributeMax) { + delta = destination.subtract(group.max()[0]); + } else { + delta = BigDecimal.ZERO; + } + + destination = destination.add(increment); + + vm.backupSelection(); + vm.clearSelection2(); + final Set selectedLineNumbers = vm.addToSelection(group.group()); + final BigDecimal deltaX = distributeOnX ? delta : BigDecimal.ZERO; + final BigDecimal deltaY = distributeOnY ? delta : BigDecimal.ZERO; + final BigDecimal deltaZ = distributeOnZ ? delta : BigDecimal.ZERO; + + final Matrix m = View.ACCURATE_ID.translate(new BigDecimal[]{deltaX, deltaY, deltaZ}); + vm.transformSelection(m, null, MiscToggleToolItem.isMovingAdjacentData(), false); + vm.restoreSelection(); + for (int number : selectedLineNumbers) { + vm.addTextLineToSelection(number); + } + } finishModification(vm, groups); } @@ -137,14 +223,14 @@ public static void distributeEqually(AlignAndDistribute axis) { final List groups = addSnapshotAndPrepareGroupSelection(vm); NLogger.debug(AlignAndDistribute.class, "Identified {0} selected group(s) for equal distribution.", groups.size()); //$NON-NLS-1$ if (groups.size() <= 2) return; - calcuateMinMaxAvgForGroups(groups, vm, axis); + calculateMinMaxAvgForGroups(groups, vm, axis); // FIXME Needs implementation! finishModification(vm, groups); } } - private static void calcuateMinMaxAvgForGroups(final List groups, final VertexManager vm, final AlignAndDistribute axis) { + private static void calculateMinMaxAvgForGroups(final List groups, final VertexManager vm, final AlignAndDistribute axis) { final List groupsToDelete = new ArrayList<>(); final boolean xAxis = axis == X || axis == X_MIN || axis == X_MAX || axis == X_AVG; final boolean yAxis = axis == Y || axis == Y_MIN || axis == Y_MAX || axis == Y_AVG; @@ -232,8 +318,9 @@ private static void finishModification(final VertexManager vm, final List