Commit 7b77043e authored by Chinmay Garde's avatar Chinmay Garde

Newton: Address initial code review concerns

parent be5e52bc
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
library newton; library newton;
import 'dart:math' as Math; import 'dart:math' as math;
part 'src/simulation.dart'; part 'src/simulation.dart';
part 'src/simulation_group.dart'; part 'src/simulation_group.dart';
......
...@@ -12,14 +12,14 @@ class FrictionSimulation extends Simulation { ...@@ -12,14 +12,14 @@ class FrictionSimulation extends Simulation {
FrictionSimulation(double drag, double position, double velocity) FrictionSimulation(double drag, double position, double velocity)
: _drag = drag, : _drag = drag,
_dragLog = Math.log(drag), _dragLog = math.log(drag),
_x = position, _x = position,
_v = velocity; _v = velocity;
double x(double time) => double x(double time) =>
_x + _v * Math.pow(_drag, time) / _dragLog - _v / _dragLog; _x + _v * math.pow(_drag, time) / _dragLog - _v / _dragLog;
double dx(double time) => _v * Math.pow(_drag, time); double dx(double time) => _v * math.pow(_drag, time);
@override @override
bool isDone(double time) => dx(time).abs() < 1.0; bool isDone(double time) => dx(time).abs() < 1.0;
......
...@@ -10,7 +10,7 @@ part of newton; ...@@ -10,7 +10,7 @@ part of newton;
class ScrollSimulation extends SimulationGroup { class ScrollSimulation extends SimulationGroup {
final double _leadingExtent; final double _leadingExtent;
final double _trailingExtent; final double _trailingExtent;
final SpringDesc _springDesc; final SpringDescription _springDesc;
final double _drag; final double _drag;
bool _isSpringing = false; bool _isSpringing = false;
...@@ -18,7 +18,7 @@ class ScrollSimulation extends SimulationGroup { ...@@ -18,7 +18,7 @@ class ScrollSimulation extends SimulationGroup {
double _offset = 0.0; double _offset = 0.0;
ScrollSimulation(double position, double velocity, double leading, ScrollSimulation(double position, double velocity, double leading,
double trailing, SpringDesc spring, double drag) double trailing, SpringDescription spring, double drag)
: _leadingExtent = leading, : _leadingExtent = leading,
_trailingExtent = trailing, _trailingExtent = trailing,
_springDesc = spring, _springDesc = spring,
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
part of newton; part of newton;
class SpringDesc { class SpringDescription {
/// The mass of the spring (m) /// The mass of the spring (m)
final double mass; final double mass;
...@@ -16,16 +16,24 @@ class SpringDesc { ...@@ -16,16 +16,24 @@ class SpringDesc {
/// constructor provided for this purpose /// constructor provided for this purpose
final double damping; final double damping;
SpringDesc(this.mass, this.springConstant, this.damping); SpringDescription({double mass, double springConstant, double damping})
: mass = mass,
springConstant = springConstant,
damping = damping {
assert(mass != null);
assert(springConstant != null);
assert(damping != null);
}
/// Create a spring given the mass, spring constant and the damping ratio. The /// Create a spring given the mass, spring constant and the damping ratio. The
/// damping ratio is especially useful trying to determing the type of spring /// damping ratio is especially useful trying to determing the type of spring
/// to create. A ratio of 1.0 creates a critically damped spring, > 1.0 /// to create. A ratio of 1.0 creates a critically damped spring, > 1.0
/// creates an overdamped spring and < 1.0 an underdamped one. /// creates an overdamped spring and < 1.0 an underdamped one.
SpringDesc.withDampingRatio(double mass, double springConstant, double zeta) SpringDescription.withDampingRatio(
: this.mass = mass, {double mass, double springConstant, double ratio: 1.0})
this.springConstant = springConstant, : mass = mass,
this.damping = zeta * 2.0 * Math.sqrt(mass * springConstant); springConstant = springConstant,
damping = ratio * 2.0 * math.sqrt(mass * springConstant);
} }
enum SpringType { unknown, criticallyDamped, underDamped, overDamped, } enum SpringType { unknown, criticallyDamped, underDamped, overDamped, }
...@@ -39,7 +47,8 @@ class SpringSimulation extends Simulation { ...@@ -39,7 +47,8 @@ class SpringSimulation extends Simulation {
/// A spring description with the provided spring description, start distance, /// A spring description with the provided spring description, start distance,
/// end distance and velocity. /// end distance and velocity.
SpringSimulation(SpringDesc desc, double start, double end, double velocity) SpringSimulation(
SpringDescription desc, double start, double end, double velocity)
: this._endPosition = end, : this._endPosition = end,
_solution = new _SpringSolution(desc, start - end, velocity); _solution = new _SpringSolution(desc, start - end, velocity);
......
...@@ -6,7 +6,7 @@ part of newton; ...@@ -6,7 +6,7 @@ part of newton;
abstract class _SpringSolution implements Simulatable { abstract class _SpringSolution implements Simulatable {
factory _SpringSolution( factory _SpringSolution(
SpringDesc desc, double initialPosition, double initialVelocity) { SpringDescription desc, double initialPosition, double initialVelocity) {
double cmk = double cmk =
desc.damping * desc.damping - 4 * desc.mass * desc.springConstant; desc.damping * desc.damping - 4 * desc.mass * desc.springConstant;
...@@ -27,7 +27,8 @@ abstract class _SpringSolution implements Simulatable { ...@@ -27,7 +27,8 @@ abstract class _SpringSolution implements Simulatable {
class _CriticalSolution implements _SpringSolution { class _CriticalSolution implements _SpringSolution {
final double _r, _c1, _c2; final double _r, _c1, _c2;
factory _CriticalSolution(SpringDesc desc, double distance, double velocity) { factory _CriticalSolution(
SpringDescription desc, double distance, double velocity) {
final double r = -desc.damping / (2.0 * desc.mass); final double r = -desc.damping / (2.0 * desc.mass);
final double c1 = distance; final double c1 = distance;
final double c2 = velocity / (r * distance); final double c2 = velocity / (r * distance);
...@@ -41,10 +42,10 @@ class _CriticalSolution implements _SpringSolution { ...@@ -41,10 +42,10 @@ class _CriticalSolution implements _SpringSolution {
_c1 = c1, _c1 = c1,
_c2 = c2; _c2 = c2;
double x(double time) => (_c1 + _c2 * time) * Math.pow(Math.E, _r * time); double x(double time) => (_c1 + _c2 * time) * math.pow(math.E, _r * time);
double dx(double time) { double dx(double time) {
final double power = Math.pow(Math.E, _r * time); final double power = math.pow(math.E, _r * time);
return _r * (_c1 + _c2 * time) * power + _c2 * power; return _r * (_c1 + _c2 * time) * power + _c2 * power;
} }
} }
...@@ -53,12 +54,12 @@ class _OverdampedSolution implements _SpringSolution { ...@@ -53,12 +54,12 @@ class _OverdampedSolution implements _SpringSolution {
final double _r1, _r2, _c1, _c2; final double _r1, _r2, _c1, _c2;
factory _OverdampedSolution( factory _OverdampedSolution(
SpringDesc desc, double distance, double velocity) { SpringDescription desc, double distance, double velocity) {
final double cmk = final double cmk =
desc.damping * desc.damping - 4 * desc.mass * desc.springConstant; desc.damping * desc.damping - 4 * desc.mass * desc.springConstant;
final double r1 = (-desc.damping - Math.sqrt(cmk)) / (2.0 * desc.mass); final double r1 = (-desc.damping - math.sqrt(cmk)) / (2.0 * desc.mass);
final double r2 = (-desc.damping + Math.sqrt(cmk)) / (2.0 * desc.mass); final double r2 = (-desc.damping + math.sqrt(cmk)) / (2.0 * desc.mass);
final double c2 = (velocity - r1 * distance) / (r2 - r1); final double c2 = (velocity - r1 * distance) / (r2 - r1);
final double c1 = distance - c2; final double c1 = distance - c2;
...@@ -74,18 +75,18 @@ class _OverdampedSolution implements _SpringSolution { ...@@ -74,18 +75,18 @@ class _OverdampedSolution implements _SpringSolution {
SpringType get type => SpringType.overDamped; SpringType get type => SpringType.overDamped;
double x(double time) => double x(double time) =>
(_c1 * Math.pow(Math.E, _r1 * time) + _c2 * Math.pow(Math.E, _r2 * time)); (_c1 * math.pow(math.E, _r1 * time) + _c2 * math.pow(math.E, _r2 * time));
double dx(double time) => (_c1 * _r1 * Math.pow(Math.E, _r1 * time) + double dx(double time) => (_c1 * _r1 * math.pow(math.E, _r1 * time) +
_c2 * _r2 * Math.pow(Math.E, _r2 * time)); _c2 * _r2 * math.pow(math.E, _r2 * time));
} }
class _UnderdampedSolution implements _SpringSolution { class _UnderdampedSolution implements _SpringSolution {
final double _w, _r, _c1, _c2; final double _w, _r, _c1, _c2;
factory _UnderdampedSolution( factory _UnderdampedSolution(
SpringDesc desc, double distance, double velocity) { SpringDescription desc, double distance, double velocity) {
final double w = Math.sqrt(4.0 * desc.mass * desc.springConstant - final double w = math.sqrt(4.0 * desc.mass * desc.springConstant -
desc.damping * desc.damping) / desc.damping * desc.damping) /
(2.0 * desc.mass); (2.0 * desc.mass);
final double r = -(desc.damping / 2.0 * desc.mass); final double r = -(desc.damping / 2.0 * desc.mass);
...@@ -103,13 +104,13 @@ class _UnderdampedSolution implements _SpringSolution { ...@@ -103,13 +104,13 @@ class _UnderdampedSolution implements _SpringSolution {
SpringType get type => SpringType.underDamped; SpringType get type => SpringType.underDamped;
double x(double time) => Math.pow(Math.E, _r * time) * double x(double time) => math.pow(math.E, _r * time) *
(_c1 * Math.cos(_w * time) + _c2 * Math.sin(_w * time)); (_c1 * math.cos(_w * time) + _c2 * math.sin(_w * time));
double dx(double time) { double dx(double time) {
final double power = Math.pow(Math.E, _r * time); final double power = math.pow(math.E, _r * time);
final double cosine = Math.cos(_w * time); final double cosine = math.cos(_w * time);
final double sine = Math.sin(_w * time); final double sine = math.sin(_w * time);
return power * (_c2 * _w * cosine - _c1 * _w * sine) + return power * (_c2 * _w * cosine - _c1 * _w * sine) +
_r * power * (_c2 * sine + _c1 * cosine); _r * power * (_c2 * sine + _c1 * cosine);
......
...@@ -58,27 +58,32 @@ void main() { ...@@ -58,27 +58,32 @@ void main() {
}); });
test('spring_types', () { test('spring_types', () {
var crit = new SpringSimulation( var crit = new SpringSimulation(new SpringDescription.withDampingRatio(
new SpringDesc.withDampingRatio(1.0, 100.0, 1.0), 0.0, 300.0, 0.0); mass: 1.0, springConstant: 100.0), 0.0, 300.0, 0.0);
expect(crit.type, SpringType.criticallyDamped); expect(crit.type, SpringType.criticallyDamped);
var under = new SpringSimulation( crit = new SpringSimulation(new SpringDescription.withDampingRatio(
new SpringDesc.withDampingRatio(1.0, 100.0, 0.75), 0.0, 300.0, 0.0); mass: 1.0, springConstant: 100.0, ratio: 1.0), 0.0, 300.0, 0.0);
expect(crit.type, SpringType.criticallyDamped);
var under = new SpringSimulation(new SpringDescription.withDampingRatio(
mass: 1.0, springConstant: 100.0, ratio: 0.75), 0.0, 300.0, 0.0);
expect(under.type, SpringType.underDamped); expect(under.type, SpringType.underDamped);
var over = new SpringSimulation( var over = new SpringSimulation(new SpringDescription.withDampingRatio(
new SpringDesc.withDampingRatio(1.0, 100.0, 1.25), 0.0, 300.0, 0.0); mass: 1.0, springConstant: 100.0, ratio: 1.25), 0.0, 300.0, 0.0);
expect(over.type, SpringType.overDamped); expect(over.type, SpringType.overDamped);
// Just so we don't forget how to create a desc without the ratio. // Just so we don't forget how to create a desc without the ratio.
var other = var other = new SpringSimulation(
new SpringSimulation(new SpringDesc(1.0, 100.0, 20.0), 0.0, 20.0, 20.0); new SpringDescription(mass: 1.0, springConstant: 100.0, damping: 20.0),
0.0, 20.0, 20.0);
expect(other.type, SpringType.criticallyDamped); expect(other.type, SpringType.criticallyDamped);
}); });
test('crit_spring', () { test('crit_spring', () {
var crit = new SpringSimulation( var crit = new SpringSimulation(new SpringDescription.withDampingRatio(
new SpringDesc.withDampingRatio(1.0, 100.0, 1.0), 0.0, 500.0, 0.0); mass: 1.0, springConstant: 100.0, ratio: 1.0), 0.0, 500.0, 0.0);
expect(crit.type, SpringType.criticallyDamped); expect(crit.type, SpringType.criticallyDamped);
expect(crit.isDone(0.0), false); expect(crit.isDone(0.0), false);
...@@ -99,8 +104,8 @@ void main() { ...@@ -99,8 +104,8 @@ void main() {
}); });
test('overdamped_spring', () { test('overdamped_spring', () {
var over = new SpringSimulation( var over = new SpringSimulation(new SpringDescription.withDampingRatio(
new SpringDesc.withDampingRatio(1.0, 100.0, 1.25), 0.0, 500.0, 0.0); mass: 1.0, springConstant: 100.0, ratio: 1.25), 0.0, 500.0, 0.0);
expect(over.type, SpringType.overDamped); expect(over.type, SpringType.overDamped);
expect(over.isDone(0.0), false); expect(over.isDone(0.0), false);
...@@ -118,8 +123,8 @@ void main() { ...@@ -118,8 +123,8 @@ void main() {
}); });
test('underdamped_spring', () { test('underdamped_spring', () {
var under = new SpringSimulation( var under = new SpringSimulation(new SpringDescription.withDampingRatio(
new SpringDesc.withDampingRatio(1.0, 100.0, 0.25), 0.0, 300.0, 0.0); mass: 1.0, springConstant: 100.0, ratio: 0.25), 0.0, 300.0, 0.0);
expect(under.type, SpringType.underDamped); expect(under.type, SpringType.underDamped);
expect(under.isDone(0.0), false); expect(under.isDone(0.0), false);
...@@ -135,7 +140,8 @@ void main() { ...@@ -135,7 +140,8 @@ void main() {
}); });
test('test_kinetic_scroll', () { test('test_kinetic_scroll', () {
var spring = new SpringDesc.withDampingRatio(1.0, 50.0, 0.5); var spring = new SpringDescription.withDampingRatio(
mass: 1.0, springConstant: 50.0, ratio: 0.5);
var scroll = new ScrollSimulation(100.0, 800.0, 0.0, 300.0, spring, 0.3); var scroll = new ScrollSimulation(100.0, 800.0, 0.0, 300.0, spring, 0.3);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment