Skip to content

Commit

Permalink
Add angular acceleration generator
Browse files Browse the repository at this point in the history
  • Loading branch information
knokko committed Sep 8, 2024
1 parent cfe5cff commit 3511545
Show file tree
Hide file tree
Showing 13 changed files with 215 additions and 12 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ a module.
## Supported quantities
- [x] acceleration
- [x] angle
- [ ] angular acceleration
- [x] angular acceleration
- [x] angular speed (spin)
- [ ] angular momentum
- [x] area
Expand Down
57 changes: 57 additions & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,51 @@ obtain a *spin*.
}
```

## Angular acceleration classes
Angular acceleration classes represent *angular accelerations*: the
speed at which the spin/angular velocity of an object is changed.
All angular acceleration classes must use floating-point numbers.

### Arithmetic
- The product of an *angular acceleration* and a *duration* yields a *spin*
(angular velocity)

### className
The Kotlin class name of the class that should represent the angular
acceleration.

### floatType
The floating-point type that will represent the angular acceleration,
must be either `Float` or `Double`.

### spin
The optional class name of the *spin* that should be linked to this
angular acceleration. When specified, instances of this class can be
multiplied by instances of *Duration* to obtain an instance of the
spin class.

### createNumberExtensions
When you enable `createNumberExtensions`, you can use e.g. `10.radps2` to
obtain 10 rad/s^2.

### Example
```json
{
"moduleName": "example-angular-acceleration",
"packageName": "fixie.angle.acceleration",
"angularAccelerations": [{
"className": "AngularAcceleration",
"floatType": "Double",
"spin": "SpinClassName",
"createNumberExtensions": true
}],
"spins": [{
"className": "SpinClassName",
...
}]
}
```

## Area classes
Area classes represent areas (like 10 square meter or 10 square miles).
Currently, all area classes must use floating-point numbers, because
Expand Down Expand Up @@ -787,6 +832,7 @@ change this in the future.

### Arithmetic
- The product of a *spin* and a *duration* is an *angle*.
- The quotient of a *spin* and a *duration* yields an *angular acceleration*

### className
The Kotlin class name of the class that will represent the spin.
Expand Down Expand Up @@ -818,6 +864,12 @@ this spin class should be linked. When linked, you can
multiply instances of this spin class with a *duration*
to obtain an instance of the angle class.

### acceleration
The optional class name of the *angular acceleration* class
to which this spin class should be linked. When linked, you
can divide instances of this spin class by a *duration*
to obtain an instance of the angular acceleration class.

### createNumberExtensions
Whether extension functions should be generated on primitive
integer types and floating-point types. If you enable this,
Expand All @@ -836,11 +888,16 @@ can enable this.
"oneUnit": "Radians per second",
"displayUnit": "Degrees per second",
"angle": "AngleClass",
"acceleration": "AngularAccelerationClass",
"createNumberExtensions": true
}],
"angles": [{
"className": "AngleClass",
...
}],
"angularAccelerations": [{
"className": "AngularAccelerationClass",
...
}]
}
```
Expand Down
20 changes: 20 additions & 0 deletions example-configs/angles.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,28 @@
"oneUnit": "%SPIN_UNIT1%",
"displayUnit": "%SPIN_UNIT2%",
"angle": "ConnectedAngle",
"acceleration": "FloatAcceleration",
"createNumberExtensions": "%NUMBER_EXTENSIONS1%"
}],
"angularAccelerations": [
{
"className": "LonelyAcceleration",
"floatType": "%FLOAT_TYPE%",
"createNumberExtensions": "%NUMBER_EXTENSIONS1%"
},
{
"className": "FloatAcceleration",
"floatType": "Float",
"spin": "Spin",
"createNumberExtensions": false
},
{
"className": "DoubleAcceleration",
"floatType": "Double",
"spin": "Spin",
"createNumberExtensions": "%NUMBER_EXTENSIONS2%"
}
],
"variations": [
{
"%INT_TYPE%": ["Byte", "UByte", "Short", "UShort", "Int", "UInt", "Long", "ULong"],
Expand Down
7 changes: 7 additions & 0 deletions example-configs/balls2d.gddl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
allowComparisons = false,
spin = "Spin"
}],
angularAccelerations = [{
className = "AngularAcceleration",
floatType = "Double",
spin = "Spin",
createNumberExtensions = true
}],
densities = [{
className = "Density",
number = "FixDensity",
Expand Down Expand Up @@ -113,6 +119,7 @@
oneUnit = "Degrees per second",
displayUnit = "Degrees per second",
angle = "Angle",
acceleration = "AngularAcceleration",
createNumberExtensions = true
}]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package fixie.generator.acceleration

import fixie.generator.number.FloatType
import fixie.generator.quantity.FloatQuantityClass
import fixie.generator.quantity.QuantityUnit
import fixie.generator.spin.SpinClass

class AngularAccelerationClass(
className: String,
floatType: FloatType,
val spinClassName: String?,
createNumberExtensions: Boolean
) : FloatQuantityClass(className, floatType, createNumberExtensions) {

var spin: SpinClass? = null

override fun getSupportedUnits() = listOf(
QuantityUnit(
"RADPS2", "", "rad/s^2", "radps2", 0.0001, 1e6, 1.0
)
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package fixie.generator.acceleration

import fixie.generator.quantity.FloatQuantityClassGenerator
import java.io.PrintWriter

class AngularAccelerationClassGenerator(
writer: PrintWriter,
quantity: AngularAccelerationClass,
packageName: String
) : FloatQuantityClassGenerator<AngularAccelerationClass>(writer, quantity, packageName) {

override fun getImports() = super.getImports() + arrayOf("kotlin.time.Duration", "kotlin.time.DurationUnit")

override fun generateToDoubleComment() {
writer.println("\t/** Gets the angular acceleration value, in rad/s^2 */")
}

override fun generateToString() {
writer.println()
writer.println("\toverride fun toString() = String.format(\"%.2f%s\", value, \"rad/s^2\")")
}

override fun generateArithmetic() {
super.generateArithmetic()

if (quantity.spin != null) {
writer.println()
writer.println("\toperator fun times(right: Duration) = value * ${quantity.spinClassName}.RADIANS_PER_SECOND * right.toDouble(DurationUnit.SECONDS)")
}
}

override fun generateExtensionFunctions() {
super.generateExtensionFunctions()

if (quantity.spin != null) {
writer.println()
writer.println("operator fun Duration.times(right: ${quantity.className}) = right * this")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package fixie.generator.acceleration

import fixie.generator.quantity.FloatQuantityTestsGenerator
import java.io.PrintWriter

class AngularAccelerationTestsGenerator(
writer: PrintWriter,
quantity: AngularAccelerationClass,
packageName: String
) : FloatQuantityTestsGenerator<AngularAccelerationClass>(writer, quantity, packageName) {

override fun getImports() = super.getImports() + arrayOf("kotlin.time.Duration.Companion.seconds")

override fun generateToStringBody() {
writer.println("\t\tassertEquals(\"2.34rad/s^2\", (${quantity.className}.RADPS2 * 2.34).toString())")
}

override fun generateArithmeticBody() {
super.generateArithmeticBody()

if (quantity.spin != null) {
writer.println("\t\tassertEquals(0.8, ((${quantity.className}.RADPS2 * 0.2) * 4.seconds).toDouble(SpinUnit.RADIANS_PER_SECOND), 0.01)")
}
}

override fun generateExtensionFunctionsBody() {
super.generateExtensionFunctionsBody()

if (quantity.spin != null) {
writer.println("\t\tassertEquals(0.8, (4.seconds * (${quantity.className}.RADPS2 * 0.2)).toDouble(SpinUnit.RADIANS_PER_SECOND), 0.01)")
}
}
}
7 changes: 6 additions & 1 deletion src/main/kotlin/fixie/generator/module/FixieModule.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fixie.generator.module

import fixie.generator.acceleration.AccelerationClass
import fixie.generator.acceleration.AngularAccelerationClass
import fixie.generator.angle.AngleClass
import fixie.generator.area.AreaClass
import fixie.generator.density.DensityClass
Expand All @@ -22,6 +23,7 @@ class FixieModule(
val numbers: List<NumberClass>,
val accelerations: List<AccelerationClass> = emptyList(),
val angles: List<AngleClass> = emptyList(),
val angularAccelerations: List<AngularAccelerationClass> = emptyList(),
val areas: List<AreaClass> = emptyList(),
val volumes: List<VolumeClass> = emptyList(),
val masses: List<MassClass> = emptyList(),
Expand Down Expand Up @@ -112,13 +114,16 @@ class FixieModule(
speed.acceleration = acceleration
}
resolve(speed, squareSpeed, { it.squareClassName }) { speed, square -> speed.square = square }
resolve(spins, angularAccelerations, { it.accelerationClassName }) { spin, acceleration -> spin.acceleration = acceleration }
resolve(spins, angles, { it.angleClassName }) { spin, angle -> spin.angle = angle }
resolve(angularAccelerations, spins, { it.spinClassName }) { acceleration, spin -> acceleration.spin = spin }

val allClassNames = numbers.map { it.className } +
displacements.map { it.className } + areas.map { it.className } + volumes.map { it.className } +
speed.map { it.className } + squareSpeed.map { it.className } + accelerations.map { it.className } +
masses.map { it.className } + momenta.map { it.className } + squareMomenta.map { it.className } +
angles.map { it.className } + spins.map { it.className } + densities.map { it.className }
angles.map { it.className } + spins.map { it.className } + angularAccelerations.map { it.className } +
densities.map { it.className }

for (className in allClassNames) {
if (allClassNames.count { it == className } > 1) {
Expand Down
3 changes: 3 additions & 0 deletions src/main/kotlin/fixie/generator/module/ModuleGenerator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package fixie.generator.module

import fixie.generator.acceleration.AccelerationClassGenerator
import fixie.generator.acceleration.AccelerationTestsGenerator
import fixie.generator.acceleration.AngularAccelerationClassGenerator
import fixie.generator.acceleration.AngularAccelerationTestsGenerator
import fixie.generator.angle.AngleClassGenerator
import fixie.generator.angle.AngleTestsGenerator
import fixie.generator.angle.AngleUnit
Expand Down Expand Up @@ -108,6 +110,7 @@ fun generateModule(module: FixieModule, directory: File, clearExistingFiles: Boo
generateQuantityFiles(module.squareSpeed, ::SquareSpeedClassGenerator, ::SquareSpeedTestsGenerator)
generateQuantityFiles(module.accelerations, ::AccelerationClassGenerator, ::AccelerationTestsGenerator)
generateQuantityFiles(module.angles, ::AngleClassGenerator, ::AngleTestsGenerator)
generateQuantityFiles(module.angularAccelerations, ::AngularAccelerationClassGenerator, ::AngularAccelerationTestsGenerator)
generateQuantityFiles(module.spins, ::SpinClassGenerator, ::SpinTestsGenerator)
generateQuantityFiles(module.densities, ::DensityClassGenerator, ::DensityTestsGenerator)
generateQuantityFiles(module.momenta, ::MomentumClassGenerator, ::MomentumTestsGenerator)
Expand Down
11 changes: 11 additions & 0 deletions src/main/kotlin/fixie/generator/parser/ModuleParser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import dev.gigaherz.util.gddl2.structure.GddlDocument
import dev.gigaherz.util.gddl2.structure.GddlMap
import dev.gigaherz.util.gddl2.structure.GddlValue
import fixie.generator.acceleration.AccelerationClass
import fixie.generator.acceleration.AngularAccelerationClass
import fixie.generator.angle.AngleClass
import fixie.generator.angle.AngleUnit
import fixie.generator.area.AreaClass
Expand Down Expand Up @@ -232,6 +233,13 @@ private class ModuleParser(
spinClassName = optionalString(properties, "spin", path)
)

private fun loadAngularAcceleration(properties: GddlMap, path: String) = AngularAccelerationClass(
className = requiredString(properties, "className", path),
floatType = requiredFloatType(properties, "floatType", path),
spinClassName = optionalString(properties, "spin", path),
createNumberExtensions = requiredBoolean(properties, "createNumberExtensions", path)
)

private fun loadVolume(properties: GddlMap, path: String) = VolumeClass(
className = requiredString(properties, "className", path),
floatType = requiredFloatType(properties, "floatType", path),
Expand Down Expand Up @@ -290,6 +298,7 @@ private class ModuleParser(
oneUnit = requiredUnit(properties, "oneUnit", path, SpinUnit.entries),
displayUnit = requiredUnit(properties, "displayUnit", path, SpinUnit.entries),
angleClassName = optionalString(properties, "angle", path),
accelerationClassName = optionalString(properties, "acceleration", path),
createNumberExtensions = requiredBoolean(properties, "createNumberExtensions", path)
)

Expand Down Expand Up @@ -362,6 +371,7 @@ private class ModuleParser(

val accelerations = mapList(root, "accelerations", "(root)", ::loadAcceleration)
val angles = mapList(root, "angles", "(root)", ::loadAngle)
val angularAccelerations = mapList(root, "angularAccelerations", "(root)", ::loadAngularAcceleration)
val volumes = mapList(root, "volumes", "(root)", ::loadVolume)
val areas = mapList(root, "areas", "(root)", ::loadArea)
val displacements = mapList(root, "displacements", "(root)", ::loadDisplacement)
Expand All @@ -380,6 +390,7 @@ private class ModuleParser(
numbers = numbers,
accelerations = accelerations,
angles = angles,
angularAccelerations = angularAccelerations,
volumes = volumes,
areas = areas,
displacements = displacements,
Expand Down
3 changes: 3 additions & 0 deletions src/main/kotlin/fixie/generator/spin/SpinClass.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fixie.generator.spin

import fixie.generator.acceleration.AngularAccelerationClass
import fixie.generator.angle.AngleClass
import fixie.generator.number.FloatType
import fixie.generator.quantity.FloatQuantityClass
Expand All @@ -11,10 +12,12 @@ class SpinClass(
val oneUnit: SpinUnit,
val displayUnit: SpinUnit,
val angleClassName: String?,
val accelerationClassName: String?,
createNumberExtensions: Boolean
) : FloatQuantityClass(className, floatType, createNumberExtensions) {

var angle: AngleClass? = null
var acceleration: AngularAccelerationClass? = null

override fun getSupportedUnits() = SpinUnit.entries.map {
QuantityUnit(
Expand Down
13 changes: 6 additions & 7 deletions src/main/kotlin/fixie/generator/spin/SpinClassGenerator.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package fixie.generator.spin

import fixie.generator.number.FloatType
import fixie.generator.quantity.FloatQuantityClassGenerator
import java.io.PrintWriter

Expand All @@ -10,7 +9,7 @@ class SpinClassGenerator(
packageName: String
) : FloatQuantityClassGenerator<SpinClass>(writer, spin, packageName) {

override fun getImports() = super.getImports() + if (quantity.angleClassName != null) {
override fun getImports() = super.getImports() + if (quantity.angle != null || quantity.acceleration != null) {
arrayOf("kotlin.time.Duration", "kotlin.time.DurationUnit")
} else emptyArray()

Expand All @@ -33,11 +32,11 @@ class SpinClassGenerator(
writer.println("\toperator fun times(right: Duration) = ${quantity.angleClassName}.$functionName(value * right.toDouble(DurationUnit.SECONDS))")
}

// TODO Angular acceleration?
// if (speed.acceleration != null) {
// writer.println()
// writer.println("\toperator fun div(right: Duration) = toDouble(SpeedUnit.METERS_PER_SECOND) * ${speed.acceleration.className}.MPS2 / right.toDouble(DurationUnit.SECONDS)")
// }
if (quantity.acceleration != null) {
writer.println()
writer.println("\toperator fun div(right: Duration) = toDouble(SpinUnit.RADIANS_PER_SECOND) * " +
"${quantity.accelerationClassName}.RADPS2 / right.toDouble(DurationUnit.SECONDS)")
}
}

override fun generateExtensionFunctions() {
Expand Down
Loading

0 comments on commit 3511545

Please sign in to comment.