@@ -0,0 +1,33 @@
package gw.specContrib.dimensions.physics
uses java.math.BigDecimal

interface IUnit<B extends Number, D extends IDimension<D, B>, U extends IUnit<B, D, U>> extends IDimension<U, B>, UnitConstants {
property get UnitName() : String
property get UnitSymbol() : String
property get BaseUnitFactor() : B

function multiply( amount: Number ) : D {
return new D( amount, this )
}

override function toNumber() : B {
return BaseUnitFactor
}

override function fromNumber( n: B ) : U {
return null
}

override function numberType() : Class<B> {
return B
}

override function compareTo( o: U ) : int {
return UnitName.compareTo( o.UnitName )
}

function equals( u: U ) : boolean {
return UnitName.equals( u.UnitName ) &&
BaseUnitFactor.equals( u.BaseUnitFactor )
}
}
@@ -0,0 +1,24 @@
package gw.specContrib.dimensions.physics

uses java.math.BigDecimal

final class Length extends AbstractDim<LengthUnit, Length> {
/**
* @param value Length in specified units
* @param unit Length unit for value, default is Micromillimetres
* @param displayUnit Unit in which to display this Length
*/
construct( value: BigDecimal, unit: LengthUnit, displayUnit: LengthUnit ) {
super( value * unit.BaseUnitFactor, displayUnit, LengthUnit.Micros )
}
construct( value: BigDecimal, unit: LengthUnit ) {
this( value, unit, unit )
}

function divide( t: Time ) : Rate {
return new Rate( toNumber() / t.toNumber(), RateUnit.BASE, new( Unit, t.Unit ) )
}
function divide( r: Rate ) : Time {
return new Time( toNumber() / r.toNumber(), Nanos, r.Unit.TimeUnit )
}
}
@@ -0,0 +1,39 @@
package gw.specContrib.dimensions.physics
uses java.math.BigDecimal

enum LengthUnit implements IUnit<BigDecimal, Length, LengthUnit> {
Micros( 1bd, "Micrometres", "µm" ),
Millis( 1000bd, "Millimeters", "mm" ),
Meters( 1000000bd, "Meters", "m" ),
Kilometers( 1000000000bd, "Kilometers", "km" ),
Inches( 25400bd, "Inches", "in" ),
Feet( 12*25400bd, "Feet", "ft" ),
Yards( 3*12*25400bd, "Yards", "yd" ),
Miles( 1609344000bd, "Miles", "mi" )

var _micros: BigDecimal as Micrometres
var _name: String
var _symbol: String

private construct( micros: BigDecimal, name: String, symbol: String ) {
_micros = micros
_name = name
_symbol = symbol
}

override property get UnitName() : String {
return _name
}

override property get UnitSymbol() : String {
return _symbol
}

override property get BaseUnitFactor() : BigDecimal {
return Micrometres
}

function divide( t: TimeUnit ) : RateUnit {
return new RateUnit( this, t )
}
}
@@ -0,0 +1,23 @@
package gw.specContrib.dimensions.physics

uses java.math.BigDecimal
uses java.math.RoundingMode
uses java.math.MathContext

final class Momentum extends AbstractDim<MomentumUnit, Momentum> {
/**
* @param value Momentum in specified units
* @param unit Momentum unit, default is millis / second
* @param displayUnit Unit in which to display this rate
*/
construct( value : BigDecimal, unit: MomentumUnit, displayUnit: MomentumUnit ) {
super( value * unit.BaseUnitFactor, displayUnit, MomentumUnit.BASE )
}
construct( value : BigDecimal, unit: MomentumUnit ) {
this( value, unit, unit )
}

function divide( w: Weight ) : Rate {
return new Rate( toNumber() / w.toNumber(), RateUnit.BASE, Unit.RateUnit )
}
}
@@ -0,0 +1,27 @@
package gw.specContrib.dimensions.physics

uses java.math.BigDecimal

final class MomentumUnit implements IUnit<BigDecimal, Momentum, MomentumUnit> {
public static var BASE: MomentumUnit = new ( Micros, RateUnit.BASE )

var _weightUnit: WeightUnit as readonly WeightUnit
var _rateUnit: RateUnit as readonly RateUnit

construct( weightUnit: WeightUnit, rateUnit: RateUnit ) {
_weightUnit = weightUnit
_rateUnit = rateUnit
}

override property get UnitName() : String {
return _weightUnit.UnitName + " " + _rateUnit.UnitName
}

override property get UnitSymbol() : String {
return _weightUnit.UnitSymbol + " " + _rateUnit.UnitSymbol
}

override property get BaseUnitFactor() : BigDecimal {
return _weightUnit.BaseUnitFactor * _rateUnit.BaseUnitFactor
}
}
@@ -0,0 +1,25 @@
package gw.specContrib.dimensions.physics
uses junit.framework.TestCase

class PhysicsTest extends gw.test.TestClass implements UnitConstants {
function testMe() {
var rate = 50 *mph
var time = 3 *min
var distance = rate * time
assertTrue( 2.5 *mi == distance )
assertTrue( 4.02336 *km == distance.to( km ) )
time = distance / rate
assertTrue( 3 *min == distance / rate )

var mass = 20 * g
var acc = 9.8 * (m/s/s)
var force = mass * acc
assertTrue( 196 *(g*(m/s/s)) == force )
assertTrue( 0.196bd *(kg*(m/s/s)) == force.to( kg*(m/s/s) ) )
assertTrue( "1.417670714837139298612298722559885 lb ft/s/s" == force.to( lb*(ft/s/s) ).toString() )

var momentum = mass * rate
assertTrue( 1000 *(g*(mi/hr)) == mass * rate )
assertTrue( 0.44704 *(kg*(m/s)) == momentum.to( Ns ) )
}
}
@@ -0,0 +1,27 @@
package gw.specContrib.dimensions.physics

uses java.math.BigDecimal
uses java.math.RoundingMode
uses java.math.MathContext

final class Rate extends AbstractDim<RateUnit, Rate> {
/**
* @param value Rate in specified units
* @param unit Rate unit, default is millis / second
* @param displayUnit Unit in which to display this rate
*/
construct( value : BigDecimal, unit: RateUnit, displayUnit: RateUnit ) {
super( value * unit.BaseUnitFactor, displayUnit, RateUnit.BASE )
}
construct( value : BigDecimal, unit: RateUnit ) {
this( value, unit, unit )
}

function multiply( t: Time ) : Length {
return new Length( toNumber() * t.toNumber(), Micros, Unit.LengthUnit )
}

function divice( t: Time ) : Acceleration {
return new Acceleration( toNumber() / t.toNumber(), AccelerationUnit.BASE, new( Unit, t.Unit ) )
}
}
@@ -0,0 +1,30 @@
package gw.specContrib.dimensions.physics
uses java.math.BigDecimal

final class RateUnit implements IUnit<BigDecimal, Rate, RateUnit> {
public static var BASE: RateUnit = new( LengthUnit.Micros, TimeUnit.Nanos )

var _lengthUnit: LengthUnit as readonly LengthUnit
var _timeUnit: TimeUnit as readonly TimeUnit

construct( lengthUnit: LengthUnit, timeUnit: TimeUnit ) {
_lengthUnit = lengthUnit
_timeUnit = timeUnit
}

override property get UnitName() : String {
return _lengthUnit.UnitName + "/" + _timeUnit.UnitName
}

override property get UnitSymbol() : String {
return _lengthUnit.UnitSymbol + "/" + _timeUnit.UnitSymbol
}

override property get BaseUnitFactor() : BigDecimal {
return _lengthUnit.BaseUnitFactor / _timeUnit.BaseUnitFactor
}

function divide( t: TimeUnit ) : AccelerationUnit {
return new AccelerationUnit( this, t )
}
}
@@ -0,0 +1,14 @@
new PhysicsTest().testMe()
//extends UnitConstantsImpl
//
// var rate = 50 *mph
// var time = 3 *min
// var distance = rate * time
//
// var mass = 20 * g
// var acc = 9.8 * (m/s/s)
// var force = mass * acc
//
// var momentum = mass * rate
// print( momentum )
// print( momentum.toNumber( Ns ).scale() )
@@ -0,0 +1,25 @@
package gw.specContrib.dimensions.physics

uses java.math.BigDecimal

final class Time extends AbstractDim<TimeUnit, Time> {
/**
* @param value Time period in specified units
* @param unit Unit of time vor value
* @param displayUnit Unit of time in which to display this Time
*/
construct( value : BigDecimal, unit: TimeUnit, displayUnit: TimeUnit ) {
super( value * unit.BaseUnitFactor, displayUnit, TimeUnit.Nanos )
}
construct( value : BigDecimal, unit: TimeUnit ) {
this( value, unit, unit )
}

override function fromNumber( p0: BigDecimal ) : Time {
return new Time( p0, Nanos, Unit )
}

function multiply( r: Rate ) : Length {
return new Length( toNumber() * r.toNumber(), Micros, r.Unit.LengthUnit )
}
}
@@ -0,0 +1,36 @@
package gw.specContrib.dimensions.physics
uses java.math.BigDecimal

enum TimeUnit implements IUnit<BigDecimal, Time, TimeUnit> {
Nanos( 1bd, "Nanoseconds", "ns" ),
Micros( 1000bd, "Microseconds", "µs" ),
Millis( 1000000bd, "Milliseconds", "ms" ),
Seconds( 1000000000bd, "Seconds", "s" ),
Minutes( 60*1000000000bd, "Minutes", "min" ),
Hours( 60*60*1000000000bd, "Hours", "h" ),
Days( 24*60*60*1000000000bd, "Days", "d" ),
Weeks( 7*24*60*60*1000000000bd, "Weeks", "wk" ),
Years( 31556925993600000bd, "Years", "yr" ) // tropical year

var _nanos: BigDecimal as Nanoseconds
var _name: String
var _symbol: String

private construct( nanos: BigDecimal, name: String, symbol: String ) {
_nanos = nanos
_name = name
_symbol = symbol
}

override property get UnitName() : String {
return _name
}

override property get UnitSymbol() : String {
return _symbol
}

override property get BaseUnitFactor() : BigDecimal {
return Nanoseconds
}
}
@@ -0,0 +1,44 @@
package gw.specContrib.dimensions.physics

interface UnitConstants {
var mum: LengthUnit = Micros
var mm: LengthUnit = Millis
var m: LengthUnit = Meters
var km: LengthUnit = Kilometers
var inch: LengthUnit = Inches
var ft: LengthUnit = Feet
var yds: LengthUnit = Yards
var mi: LengthUnit = Miles

var ns: TimeUnit = Nanos
var mus: TimeUnit = Micros
var ms: TimeUnit = Millis
var s: TimeUnit = Seconds
var min: TimeUnit = Minutes
var hr: TimeUnit = Hours
var d: TimeUnit = Days
var wk: TimeUnit = Weeks
var yr: TimeUnit = Years

var amu: WeightUnit = AMUs
var mug: WeightUnit = Micros
var mg: WeightUnit = Millis
var g: WeightUnit = Grams
var kg: WeightUnit = Kilograms
var ct: WeightUnit = Carats
var dr: WeightUnit = Drams
var gr: WeightUnit = Grains
var Nt: WeightUnit = Newtons
var oz: WeightUnit = Ounces
var ozt: WeightUnit = TroyOunces
var lb: WeightUnit = Pounds
var st: WeightUnit = Stones
var sht: WeightUnit = Tons
var lt: WeightUnit = TonsUK
var tonne: WeightUnit = Tonnes
var Mo: WeightUnit = Solars

var mph: RateUnit = mi/hr
var Ns: MomentumUnit = kg*(m/s)
var N: ForceUnit = kg*(m/s/s)
}
@@ -0,0 +1,4 @@
package gw.specContrib.dimensions.physics

class UnitConstantsImpl implements UnitConstants {
}
@@ -0,0 +1,24 @@
package gw.specContrib.dimensions.physics
uses java.math.BigDecimal

final class Weight extends AbstractDim<WeightUnit, Weight> {
/**
* @param value Length in specified units
* @param unit Length unit for value, default is Micromillimetres
* @param displayUnit Unit in which to display this Length
*/
construct( value: BigDecimal, unit: WeightUnit, displayUnit: WeightUnit ) {
super( value * unit.BaseUnitFactor, displayUnit, WeightUnit.Micros )
}
construct( value : BigDecimal, unit: WeightUnit ) {
this( value, unit, unit )
}

function multiply( a: Acceleration ) : Force {
return new Force( toNumber() * a.toNumber(), ForceUnit.BASE, new( Unit, a.Unit ) )
}

function multiply( r: Rate ) : Momentum {
return new Momentum( toNumber() * r.toNumber(), MomentumUnit.BASE, new( Unit, r.Unit ) )
}
}
@@ -0,0 +1,53 @@
package gw.specContrib.dimensions.physics

uses java.math.BigDecimal

enum WeightUnit implements IUnit<BigDecimal, Weight, WeightUnit> {
AMUs( 1.6605402e-18, "AMUs", "amu" ),
Micros( 1bd, "Micrograms", "µg" ),
Millis( 1000bd, "Milligrams", "mg" ),
Grams( 1000000bd, "Grams", "g" ),
Kilograms( 1000000000bd, "Kilograms", "kg" ),
Carats( 200000bd, "Carats", "ct" ),
Drams( 1771845.195312bd, "Drams", "dr" ),
Grains( 64798.91bd, "Grains", "gr" ),
Newtons( 101971621.2978bd, "Newtons", "N" ),
Ounces( 28349523.125bd, "Ounces", "oz" ),
TroyOunces( 31103476.8bd, "Troy Ounces", "ozt" ),
Pounds( 453592370bd, "Pounds", "lb" ),
Stones( 6350293180bd, "Stones", "st" ),
Tons( 907184740000bd, "Tons (US, short)", "sht" ),
TonsUK( 1016046908800bd, "Tons (UK, long)", "lt" ),
Tonnes( 1000000000000bd, "Tonnes", "tonne" ),
Solars( 1.9889200011445836e39, "Solar Masses", "M☉" )

var _micros: BigDecimal as Micrograms
var _name: String
var _symbol: String

private construct( micros: BigDecimal, name: String, symbol: String ) {
_micros = micros
_name = name
_symbol = symbol
}

override property get UnitName() : String {
return _name
}

override property get UnitSymbol() : String {
return _symbol
}

override property get BaseUnitFactor() : BigDecimal {
return Micrograms
}

function multiply( rate: RateUnit ) : MomentumUnit {
return new( this, rate )
}

function multiply( acc: AccelerationUnit ) : ForceUnit {
return new( this, acc )
}
}
@@ -24,7 +24,7 @@ public static Test suite()
BytecodeOptions.enableAggressiveVerification();
return new GosuScratchSuite()
.withTestEnvironment( new ScratchTestEnvironment() )
.withTest( "gw.internal.gosu.parser.classTests.gwtest.dynamic.JsonTest" )
.withTest( "gw.lang.spec_old.dimension.DimensionTest" )
;
}