Skip to content

Commit

Permalink
Fix problem with the arc expander not working with inches (#2267)
Browse files Browse the repository at this point in the history
  • Loading branch information
breiler committed Jul 28, 2023
1 parent b73b53a commit 14f2591
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ This file is part of Universal Gcode Sender (UGS).
import com.willwinder.universalgcodesender.gcode.util.PlaneFormatter;
import com.willwinder.universalgcodesender.i18n.Localization;
import com.willwinder.universalgcodesender.model.Position;
import com.willwinder.universalgcodesender.model.UnitUtils;

import java.text.DecimalFormat;
import java.util.*;
Expand Down Expand Up @@ -422,9 +423,9 @@ static public double parseCoord(List<String> argList, char c)
* @param end end position XYZ and rotations
* @param center center of rotation
* @param clockwise flag indicating clockwise or counter-clockwise
* @param radius radius of the arc
* @param minArcLength minimum length before expansions are made.
* @param arcSegmentLength length of segments in resulting Positions.
* @param radius radius of the arc in the same units as the given start, end and center position
* @param minArcLengthMM minimum length before expansions are made.
* @param arcSegmentLengthMM length of segments in resulting Positions.
* @param plane helper to select values for arcs across different planes
*/
static public List<Position> generatePointsAlongArcBDring(
Expand All @@ -433,12 +434,12 @@ static public List<Position> generatePointsAlongArcBDring(
final Position center,
boolean clockwise,
double radius,
double minArcLength,
double arcSegmentLength,
double minArcLengthMM,
double arcSegmentLengthMM,
PlaneFormatter plane) {
double r = radius;

// Calculate radius if necessary.
double r = radius;
if (r == 0) {
r = Math.sqrt(Math.pow(plane.axis0(start) - plane.axis0(center),2.0) + Math.pow(plane.axis1(end) - plane.axis1(center), 2.0));
}
Expand All @@ -447,25 +448,42 @@ static public List<Position> generatePointsAlongArcBDring(
double endAngle = GcodePreprocessorUtils.getAngle(center, end, plane);
double sweep = GcodePreprocessorUtils.calculateSweep(startAngle, endAngle, clockwise);

int numPoints = calculateNumberOfPointsToExpand(r, start.getUnits(), minArcLengthMM, arcSegmentLengthMM, sweep);
if (numPoints == 0) {
return Collections.emptyList();
}

return GcodePreprocessorUtils.generatePointsAlongArcBDring(start, end, center, clockwise, r, startAngle, sweep, numPoints, plane);
}

/**
* Calculates the number of points to expand an arc into
*
* @param radius the radius of the arc
* @param radiusUnits the radius units
* @param minArcLengthMM the minimum arc length
* @param arcSegmentLengthMM the arg length
* @param sweep the angle of the arc
* @return the number of segments to split the arc into to achieve the given arc segment length
*/
private static int calculateNumberOfPointsToExpand(double radius, UnitUtils.Units radiusUnits, double minArcLengthMM, double arcSegmentLengthMM, double sweep) {
// Convert units.
double arcLength = sweep * r;
double arcLengthMM = sweep * radius * UnitUtils.scaleUnits(radiusUnits, UnitUtils.Units.MM);

// If this arc doesn't meet the minimum threshold, don't expand.
if (minArcLength > 0 && arcLength < minArcLength) {
return null;
if (minArcLengthMM > 0 && arcLengthMM < minArcLengthMM) {
return 0;
}

int numPoints = 20;

if (arcSegmentLength <= 0 && minArcLength > 0) {
arcSegmentLength = (sweep * r) / minArcLength;
if (arcSegmentLengthMM <= 0 && minArcLengthMM > 0) {
arcSegmentLengthMM = (sweep * radius) / minArcLengthMM;
}

if (arcSegmentLength > 0) {
numPoints = (int)Math.ceil(arcLength/arcSegmentLength);
int numPoints = 20;
if (arcSegmentLengthMM > 0) {
numPoints = (int)Math.ceil(arcLengthMM/ arcSegmentLengthMM);
}

return GcodePreprocessorUtils.generatePointsAlongArcBDring(start, end, center, clockwise, r, startAngle, sweep, numPoints, plane);
return numPoints;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public void mouseReleased(MouseEvent exc) {
this.mousePressed = false;
this.repaint();

if (!isEnabled()) return;
if (!isEnabled() || exc == null || pressedComponent == null) return;
listeners.forEach(RoundedPanelClickListener::onReleased);

if (pressedComponent.contains(exc.getPoint())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ private static void expandArc(Position start, PointSegment endSegment, double ar
start, endSegment.point(), endSegment.center(), endSegment.isClockwise(),
endSegment.getRadius(), minArcLength, arcSegmentLength, new PlaneFormatter(endSegment.getPlaneState()));
// Create line segments from points.
if (points != null) {
if (!points.isEmpty()) {
Position startPoint = start;
for (Position nextPoint : points) {
ret.add(createLineSegment(startPoint, nextPoint, endSegment, spindleSpeed));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
Copyright 2023 Will Winder
This file is part of Universal Gcode Sender (UGS).
UGS is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
UGS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with UGS. If not, see <http://www.gnu.org/licenses/>.
*/
package com.willwinder.universalgcodesender.gcode;

import com.willwinder.universalgcodesender.gcode.util.Plane;
import com.willwinder.universalgcodesender.gcode.util.PlaneFormatter;
import com.willwinder.universalgcodesender.model.Position;
import com.willwinder.universalgcodesender.model.UnitUtils;
import org.junit.Test;

import java.util.List;

import static com.willwinder.universalgcodesender.model.UnitUtils.Units.INCH;
import static com.willwinder.universalgcodesender.model.UnitUtils.Units.MM;
import static org.junit.Assert.*;

/**
* @author Joacim Breiler
*/
public class GcodePreprocessorUtilsTest {
@Test
public void generatePointsAlongArcBDringShouldGenerateAnArc() {
Position start = new Position(0, 0, 0, MM);
Position end = new Position(10, 0, 0, MM);
Position center = new Position(5, 0, 0, MM);
double radius = 5;

List<Position> points = GcodePreprocessorUtils.generatePointsAlongArcBDring(start, end, center, true, radius, 0, 1, new PlaneFormatter(Plane.XY));
assertThatPointsAreWithinBoundary(start, end, radius, points);
assertEquals(17, points.size());
assertTrue("Coordinates are generated in wrong units", points.stream().allMatch(p -> p.getUnits() == MM));
}

@Test
public void generatePointsAlongArcBDringShouldGenerateAnArcWhenPositionsAreInInches() {
Position start = new Position(0, 0, 0, UnitUtils.Units.INCH);
Position end = new Position(10 * UnitUtils.scaleUnits(MM, INCH), 0, 0, UnitUtils.Units.INCH);
Position center = new Position(5 * UnitUtils.scaleUnits(MM, INCH), 0, 0, UnitUtils.Units.INCH);
double radius = 5 * UnitUtils.scaleUnits(MM, INCH);

List<Position> points = GcodePreprocessorUtils.generatePointsAlongArcBDring(start, end, center, true, radius, 0, 1, new PlaneFormatter(Plane.XY));
assertEquals(17, points.size());
assertThatPointsAreWithinBoundary(start, end, radius, points);
assertTrue("Coordinates are generated in wrong units", points.stream().allMatch(p -> p.getUnits() == INCH));
}

static void assertThatPointsAreWithinBoundary(Position start, Position end, double radius, List<Position> points) {
assertTrue(points.stream().allMatch(p -> p.x >= start.x));
assertTrue(points.stream().allMatch(p -> p.x <= end.x));
assertTrue(points.stream().allMatch(p -> p.y >= end.y));
assertTrue(points.stream().allMatch(p -> p.y >= end.y));
assertTrue(points.stream().allMatch(p -> p.y <= end.y + radius));
assertTrue(points.stream().allMatch(p -> p.y <= end.y + radius));
}
}

0 comments on commit 14f2591

Please sign in to comment.