Skip to content

Commit

Permalink
Handle multiple arc parameters using flag shorthand
Browse files Browse the repository at this point in the history
  • Loading branch information
jzbrooks committed Jan 18, 2025
1 parent 8e2ec00 commit 43cb46f
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,19 +106,49 @@ value class CommandString(
}
command.startsWith('A', true) -> {
val parameters =
number
.findAll(command)
.map(MatchResult::value)
.chunked(7)
.map {
if (it.size == 6) {
it.take(3).map { it.toFloat() } + it[3].map { it.toString().toFloat() } +
it.drop(4).map { it.toFloat() }
buildList {
val parameterValues = number.findAll(command).map(MatchResult::value).toMutableList()
while (parameterValues.size > 5) {
if (parameterValues[3].length > 1) {
val flagShorthand = parameterValues[3]

add(
EllipticalArcCurve.Parameter(
parameterValues.removeFirst().toFloat(),
parameterValues.removeFirst().toFloat(),
parameterValues.removeFirst().toFloat(),
mapArcFlag(flagShorthand[0].toString().toFloat()).also {
parameterValues.removeFirst()
},
mapSweepFlag(flagShorthand[1].toString().toFloat()),
Point(
parameterValues.removeFirst().toFloat(),
parameterValues.removeFirst().toFloat(),
),
),
)
} else {
it.map { it.toFloat() }
check(parameterValues.size > 6) {
"$parameterValues must have 7 distinct numerical arguments if the" +
" flags are not combined without an argument separator (space or comma)"
}

add(
EllipticalArcCurve.Parameter(
parameterValues.removeFirst().toFloat(),
parameterValues.removeFirst().toFloat(),
parameterValues.removeFirst().toFloat(),
mapArcFlag(parameterValues.removeFirst().toFloat()),
mapSweepFlag(parameterValues.removeFirst().toFloat()),
Point(
parameterValues.removeFirst().toFloat(),
parameterValues.removeFirst().toFloat(),
),
),
)
}
}.toList()
.map(::mapEllipticalArcCurveParameter)
}
}

EllipticalArcCurve(variant, parameters)
}
Expand Down Expand Up @@ -151,26 +181,19 @@ value class CommandString(
return SmoothCubicBezierCurve.Parameter(endControl, end)
}

private fun mapEllipticalArcCurveParameter(components: List<Float>): EllipticalArcCurve.Parameter {
val radiusX = components[0]
val radiusY = components[1]
val angle = components[2]
val arcFlag =
when (components[3]) {
1f -> EllipticalArcCurve.ArcFlag.LARGE
0f -> EllipticalArcCurve.ArcFlag.SMALL
else -> throw IllegalArgumentException("Unexpected elliptical curve arc flag value: ${components[4]}\nExpected 0 or 1.")
}
val sweepFlag =
when (components[4]) {
1f -> EllipticalArcCurve.SweepFlag.CLOCKWISE
0f -> EllipticalArcCurve.SweepFlag.ANTICLOCKWISE
else -> throw IllegalArgumentException("Unexpected elliptical curve sweep flag value: ${components[4]}\nExpected 0 or 1.")
}
val end = Point(components[5], components[6])

return EllipticalArcCurve.Parameter(radiusX, radiusY, angle, arcFlag, sweepFlag, end)
}
private fun mapArcFlag(value: Float): EllipticalArcCurve.ArcFlag =
when (value) {
1f -> EllipticalArcCurve.ArcFlag.LARGE
0f -> EllipticalArcCurve.ArcFlag.SMALL
else -> throw IllegalArgumentException("Unexpected elliptical curve arc flag value: $value\nExpected 0 or 1.")
}

private fun mapSweepFlag(value: Float): EllipticalArcCurve.SweepFlag =
when (value) {
1f -> EllipticalArcCurve.SweepFlag.CLOCKWISE
0f -> EllipticalArcCurve.SweepFlag.ANTICLOCKWISE
else -> throw IllegalArgumentException("Unexpected elliptical curve sweep flag value: $value\nExpected 0 or 1.")
}

companion object {
private val commandRegex = Regex("(?=[MmLlHhVvCcSsQqTtAaZz])\\s*")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import assertk.assertions.isEqualTo
import assertk.assertions.isInstanceOf
import assertk.assertions.prop
import com.jzbrooks.vgo.core.util.math.Point
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle.parameters
import org.junit.jupiter.api.Test

class ParserTests {
Expand Down

0 comments on commit 43cb46f

Please sign in to comment.