Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
d5becff7
Commit
d5becff7
authored
Nov 03, 2015
by
Adam Barth
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'newton'
parents
c7dfbc04
e5a96aca
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
749 additions
and
0 deletions
+749
-0
README.md
packages/newton/README.md
+9
-0
newton.dart
packages/newton/lib/newton.dart
+18
-0
friction_simulation.dart
packages/newton/lib/src/friction_simulation.dart
+68
-0
gravity_simulation.dart
packages/newton/lib/src/gravity_simulation.dart
+26
-0
scroll_simulation.dart
packages/newton/lib/src/scroll_simulation.dart
+67
-0
simulation.dart
packages/newton/lib/src/simulation.dart
+23
-0
simulation_group.dart
packages/newton/lib/src/simulation_group.dart
+58
-0
spring_simulation.dart
packages/newton/lib/src/spring_simulation.dart
+83
-0
spring_solution.dart
packages/newton/lib/src/spring_solution.dart
+118
-0
tolerance.dart
packages/newton/lib/src/tolerance.dart
+17
-0
utils.dart
packages/newton/lib/src/utils.dart
+10
-0
newton_test.dart
packages/newton/test/newton_test.dart
+252
-0
No files found.
packages/newton/README.md
0 → 100644
View file @
d5becff7
# Newton
[
![Build Status
](
https://travis-ci.org/flutter/newton.svg?branch=master
)
](https://travis-ci.org/flutter/newton)
[
![Coverage Status
](
https://coveralls.io/repos/domokit/newton/badge.svg?branch=master
)
](https://coveralls.io/r/domokit/newton?branch=master)
Simple Physics Simulations for Dart. Springs, friction, gravity, etc.
To run the tests:
pub get
dart test/newton_test.dart
packages/newton/lib/newton.dart
0 → 100644
View file @
d5becff7
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library
newton
;
import
'dart:math'
as
math
;
part
'src/simulation.dart'
;
part
'src/simulation_group.dart'
;
part
'src/tolerance.dart'
;
part
'src/utils.dart'
;
part
'src/friction_simulation.dart'
;
part
'src/gravity_simulation.dart'
;
part
'src/scroll_simulation.dart'
;
part
'src/spring_simulation.dart'
;
part
'src/spring_solution.dart'
;
packages/newton/lib/src/friction_simulation.dart
0 → 100644
View file @
d5becff7
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of
newton
;
class
FrictionSimulation
extends
Simulation
{
final
double
_drag
;
final
double
_dragLog
;
final
double
_x
;
final
double
_v
;
FrictionSimulation
(
double
drag
,
double
position
,
double
velocity
)
:
_drag
=
drag
,
_dragLog
=
math
.
log
(
drag
),
_x
=
position
,
_v
=
velocity
;
// Return the drag value for a FrictionSimulation whose x() and dx() values pass
// through the specified start and end position/velocity values.
//
// Total time to reach endVelocity is just: (log(endVelocity) / log(startVelocity)) / log(_drag)
// or (log(v1) - log(v0)) / log(D), given v = v0 * D^t per the dx() function below.
// Solving for D given x(time) is trickier. Algebra courtesy of Wolfram Alpha:
// x1 = x0 + (v0 * D^((log(v1) - log(v0)) / log(D))) / log(D) - v0 / log(D), find D
static
double
_dragFor
(
double
startPosition
,
double
endPosition
,
double
startVelocity
,
double
endVelocity
)
{
return
math
.
pow
(
math
.
E
,
(
startVelocity
-
endVelocity
)
/
(
startPosition
-
endPosition
));
}
// A friction simulation that starts and ends at the specified positions
// and velocities.
factory
FrictionSimulation
.
through
(
double
startPosition
,
double
endPosition
,
double
startVelocity
,
double
endVelocity
)
{
return
new
FrictionSimulation
(
_dragFor
(
startPosition
,
endPosition
,
startVelocity
,
endVelocity
),
startPosition
,
startVelocity
)
..
tolerance
=
new
Tolerance
(
velocity:
endVelocity
.
abs
());
}
double
x
(
double
time
)
=>
_x
+
_v
*
math
.
pow
(
_drag
,
time
)
/
_dragLog
-
_v
/
_dragLog
;
double
dx
(
double
time
)
=>
_v
*
math
.
pow
(
_drag
,
time
);
@override
bool
isDone
(
double
time
)
=>
dx
(
time
).
abs
()
<
this
.
tolerance
.
velocity
;
}
class
BoundedFrictionSimulation
extends
FrictionSimulation
{
BoundedFrictionSimulation
(
double
drag
,
double
position
,
double
velocity
,
double
this
.
_minX
,
double
this
.
_maxX
)
:
super
(
drag
,
position
,
velocity
);
final
double
_minX
;
final
double
_maxX
;
double
x
(
double
time
)
{
return
super
.
x
(
time
).
clamp
(
_minX
,
_maxX
);
}
bool
isDone
(
double
time
)
{
return
super
.
isDone
(
time
)
||
(
x
(
time
)
-
_minX
).
abs
()
<
tolerance
.
distance
||
(
x
(
time
)
-
_maxX
).
abs
()
<
tolerance
.
distance
;
}
}
packages/newton/lib/src/gravity_simulation.dart
0 → 100644
View file @
d5becff7
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of
newton
;
class
GravitySimulation
extends
Simulation
{
final
double
_x
;
final
double
_v
;
final
double
_a
;
final
double
_end
;
GravitySimulation
(
double
acceleration
,
double
distance
,
double
endDistance
,
double
velocity
)
:
_a
=
acceleration
,
_x
=
distance
,
_v
=
velocity
,
_end
=
endDistance
;
double
x
(
double
time
)
=>
_x
+
_v
*
time
+
0.5
*
_a
*
time
*
time
;
double
dx
(
double
time
)
=>
_v
+
time
*
_a
;
@override
bool
isDone
(
double
time
)
=>
x
(
time
).
abs
()
>=
_end
;
}
packages/newton/lib/src/scroll_simulation.dart
0 → 100644
View file @
d5becff7
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of
newton
;
/// Simulates kinetic scrolling behavior between a leading and trailing
/// boundary. Friction is applied within the extends and a spring action applied
/// at the boundaries. This simulation can only step forward.
class
ScrollSimulation
extends
SimulationGroup
{
ScrollSimulation
(
double
position
,
double
velocity
,
this
.
_leadingExtent
,
this
.
_trailingExtent
,
this
.
_spring
,
this
.
_drag
)
{
_chooseSimulation
(
position
,
velocity
,
0.0
);
}
final
double
_leadingExtent
;
final
double
_trailingExtent
;
final
SpringDescription
_spring
;
final
double
_drag
;
bool
_isSpringing
=
false
;
Simulation
_currentSimulation
;
double
_offset
=
0.0
;
@override
bool
step
(
double
time
)
=>
_chooseSimulation
(
_currentSimulation
.
x
(
time
-
_offset
),
_currentSimulation
.
dx
(
time
-
_offset
),
time
);
@override
Simulation
get
currentSimulation
=>
_currentSimulation
;
@override
double
get
currentIntervalOffset
=>
_offset
;
bool
_chooseSimulation
(
double
position
,
double
velocity
,
double
intervalOffset
)
{
if
(
_spring
==
null
&&
(
position
>
_trailingExtent
||
position
<
_leadingExtent
))
return
false
;
/// This simulation can only step forward.
if
(!
_isSpringing
)
{
if
(
position
>
_trailingExtent
)
{
_isSpringing
=
true
;
_offset
=
intervalOffset
;
_currentSimulation
=
new
ScrollSpringSimulation
(
_spring
,
position
,
_trailingExtent
,
velocity
);
return
true
;
}
else
if
(
position
<
_leadingExtent
)
{
_isSpringing
=
true
;
_offset
=
intervalOffset
;
_currentSimulation
=
new
ScrollSpringSimulation
(
_spring
,
position
,
_leadingExtent
,
velocity
);
return
true
;
}
}
if
(
_currentSimulation
==
null
)
{
_currentSimulation
=
new
FrictionSimulation
(
_drag
,
position
,
velocity
);
return
true
;
}
return
false
;
}
}
packages/newton/lib/src/simulation.dart
0 → 100644
View file @
d5becff7
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of
newton
;
abstract
class
Simulatable
{
/// The current position of the object in the simulation
double
x
(
double
time
);
/// The current velocity of the object in the simulation
double
dx
(
double
time
);
}
/// The base class for all simulations. The user is meant to instantiate an
/// instance of a simulation and query the same for the position and velocity
/// of the body at a given interval.
abstract
class
Simulation
implements
Simulatable
{
Tolerance
tolerance
=
toleranceDefault
;
/// Returns if the simulation is done at a given time
bool
isDone
(
double
time
);
}
packages/newton/lib/src/simulation_group.dart
0 → 100644
View file @
d5becff7
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of
newton
;
/// The abstract base class for all composite simulations. Concrete subclasses
/// must implement the appropriate methods to select the appropriate simulation
/// at a given time interval. The simulation group takes care to call the `step`
/// method at appropriate intervals. If more fine grained control over the the
/// step is necessary, subclasses may override `Simulatable` methods.
abstract
class
SimulationGroup
extends
Simulation
{
/// The currently active simulation
Simulation
get
currentSimulation
;
/// The time offset applied to the currently active simulation;
double
get
currentIntervalOffset
;
/// Called when a significant change in the interval is detected. Subclasses
/// must decide if the the current simulation must be switched (or updated).
/// The result is whether the simulation was switched in this step.
bool
step
(
double
time
);
double
x
(
double
time
)
{
_stepIfNecessary
(
time
);
return
currentSimulation
.
x
(
time
-
currentIntervalOffset
);
}
double
dx
(
double
time
)
{
_stepIfNecessary
(
time
);
return
currentSimulation
.
dx
(
time
-
currentIntervalOffset
);
}
@override
void
set
tolerance
(
Tolerance
t
)
{
this
.
currentSimulation
.
tolerance
=
t
;
super
.
tolerance
=
t
;
}
@override
bool
isDone
(
double
time
)
{
_stepIfNecessary
(
time
);
return
currentSimulation
.
isDone
(
time
-
currentIntervalOffset
);
}
double
_lastStep
=
-
1.0
;
void
_stepIfNecessary
(
double
time
)
{
if
(
_nearEqual
(
_lastStep
,
time
,
toleranceDefault
.
time
))
{
return
;
}
_lastStep
=
time
;
if
(
step
(
time
))
{
this
.
currentSimulation
.
tolerance
=
this
.
tolerance
;
}
}
}
packages/newton/lib/src/spring_simulation.dart
0 → 100644
View file @
d5becff7
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of
newton
;
class
SpringDescription
{
/// The mass of the spring (m)
final
double
mass
;
/// The spring constant (k)
final
double
springConstant
;
/// The damping coefficient.
/// Note: Not to be confused with the damping ratio. Use the separate
/// constructor provided for this purpose
final
double
damping
;
SpringDescription
(
{
double
this
.
mass
,
double
this
.
springConstant
,
double
this
.
damping
})
{
assert
(
mass
!=
null
);
assert
(
springConstant
!=
null
);
assert
(
damping
!=
null
);
}
/// 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
/// to create. A ratio of 1.0 creates a critically damped spring, > 1.0
/// creates an overdamped spring and < 1.0 an underdamped one.
SpringDescription
.
withDampingRatio
(
{
double
mass
,
double
springConstant
,
double
ratio:
1.0
})
:
mass
=
mass
,
springConstant
=
springConstant
,
damping
=
ratio
*
2.0
*
math
.
sqrt
(
mass
*
springConstant
);
}
enum
SpringType
{
unknown
,
criticallyDamped
,
underDamped
,
overDamped
,
}
/// Creates a spring simulation. Depending on the spring description, a
/// critically, under or overdamped spring will be created.
class
SpringSimulation
extends
Simulation
{
final
double
_endPosition
;
final
_SpringSolution
_solution
;
/// A spring description with the provided spring description, start distance,
/// end distance and velocity.
SpringSimulation
(
SpringDescription
desc
,
double
start
,
double
end
,
double
velocity
)
:
this
.
_endPosition
=
end
,
_solution
=
new
_SpringSolution
(
desc
,
start
-
end
,
velocity
);
SpringType
get
type
=>
_solution
.
type
;
double
x
(
double
time
)
=>
_endPosition
+
_solution
.
x
(
time
);
double
dx
(
double
time
)
=>
_solution
.
dx
(
time
);
@override
bool
isDone
(
double
time
)
=>
_nearEqual
(
x
(
time
),
_endPosition
,
this
.
tolerance
.
distance
)
&&
_nearZero
(
dx
(
time
),
this
.
tolerance
.
velocity
);
}
/// A SpringSimulation where the value of x() is guaranteed to have exactly the
/// end value when the simulation isDone().
class
ScrollSpringSimulation
extends
SpringSimulation
{
ScrollSpringSimulation
(
SpringDescription
desc
,
double
start
,
double
end
,
double
velocity
)
:
super
(
desc
,
start
,
end
,
velocity
);
bool
_isDone
(
double
position
,
double
velocity
)
{
return
_nearEqual
(
position
,
_endPosition
,
tolerance
.
distance
)
&&
_nearZero
(
velocity
,
tolerance
.
velocity
);
}
@override
double
x
(
double
time
)
{
double
xAtTime
=
super
.
x
(
time
);
return
_isDone
(
xAtTime
,
dx
(
time
))
?
_endPosition
:
xAtTime
;
}
@override
bool
isDone
(
double
time
)
=>
_isDone
(
x
(
time
),
dx
(
time
));
}
packages/newton/lib/src/spring_solution.dart
0 → 100644
View file @
d5becff7
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of
newton
;
abstract
class
_SpringSolution
implements
Simulatable
{
factory
_SpringSolution
(
SpringDescription
desc
,
double
initialPosition
,
double
initialVelocity
)
{
double
cmk
=
desc
.
damping
*
desc
.
damping
-
4
*
desc
.
mass
*
desc
.
springConstant
;
if
(
cmk
==
0.0
)
{
return
new
_CriticalSolution
(
desc
,
initialPosition
,
initialVelocity
);
}
else
if
(
cmk
>
0.0
)
{
return
new
_OverdampedSolution
(
desc
,
initialPosition
,
initialVelocity
);
}
else
{
return
new
_UnderdampedSolution
(
desc
,
initialPosition
,
initialVelocity
);
}
return
null
;
}
SpringType
get
type
;
}
class
_CriticalSolution
implements
_SpringSolution
{
final
double
_r
,
_c1
,
_c2
;
factory
_CriticalSolution
(
SpringDescription
desc
,
double
distance
,
double
velocity
)
{
final
double
r
=
-
desc
.
damping
/
(
2.0
*
desc
.
mass
);
final
double
c1
=
distance
;
final
double
c2
=
velocity
/
(
r
*
distance
);
return
new
_CriticalSolution
.
withArgs
(
r
,
c1
,
c2
);
}
SpringType
get
type
=>
SpringType
.
criticallyDamped
;
_CriticalSolution
.
withArgs
(
double
r
,
double
c1
,
double
c2
)
:
_r
=
r
,
_c1
=
c1
,
_c2
=
c2
;
double
x
(
double
time
)
=>
(
_c1
+
_c2
*
time
)
*
math
.
pow
(
math
.
E
,
_r
*
time
);
double
dx
(
double
time
)
{
final
double
power
=
math
.
pow
(
math
.
E
,
_r
*
time
);
return
_r
*
(
_c1
+
_c2
*
time
)
*
power
+
_c2
*
power
;
}
}
class
_OverdampedSolution
implements
_SpringSolution
{
final
double
_r1
,
_r2
,
_c1
,
_c2
;
factory
_OverdampedSolution
(
SpringDescription
desc
,
double
distance
,
double
velocity
)
{
final
double
cmk
=
desc
.
damping
*
desc
.
damping
-
4
*
desc
.
mass
*
desc
.
springConstant
;
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
c2
=
(
velocity
-
r1
*
distance
)
/
(
r2
-
r1
);
final
double
c1
=
distance
-
c2
;
return
new
_OverdampedSolution
.
withArgs
(
r1
,
r2
,
c1
,
c2
);
}
_OverdampedSolution
.
withArgs
(
double
r1
,
double
r2
,
double
c1
,
double
c2
)
:
_r1
=
r1
,
_r2
=
r2
,
_c1
=
c1
,
_c2
=
c2
;
SpringType
get
type
=>
SpringType
.
overDamped
;
double
x
(
double
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
)
+
_c2
*
_r2
*
math
.
pow
(
math
.
E
,
_r2
*
time
));
}
class
_UnderdampedSolution
implements
_SpringSolution
{
final
double
_w
,
_r
,
_c1
,
_c2
;
factory
_UnderdampedSolution
(
SpringDescription
desc
,
double
distance
,
double
velocity
)
{
final
double
w
=
math
.
sqrt
(
4.0
*
desc
.
mass
*
desc
.
springConstant
-
desc
.
damping
*
desc
.
damping
)
/
(
2.0
*
desc
.
mass
);
final
double
r
=
-(
desc
.
damping
/
2.0
*
desc
.
mass
);
final
double
c1
=
distance
;
final
double
c2
=
(
velocity
-
r
*
distance
)
/
w
;
return
new
_UnderdampedSolution
.
withArgs
(
w
,
r
,
c1
,
c2
);
}
_UnderdampedSolution
.
withArgs
(
double
w
,
double
r
,
double
c1
,
double
c2
)
:
_w
=
w
,
_r
=
r
,
_c1
=
c1
,
_c2
=
c2
;
SpringType
get
type
=>
SpringType
.
underDamped
;
double
x
(
double
time
)
=>
math
.
pow
(
math
.
E
,
_r
*
time
)
*
(
_c1
*
math
.
cos
(
_w
*
time
)
+
_c2
*
math
.
sin
(
_w
*
time
));
double
dx
(
double
time
)
{
final
double
power
=
math
.
pow
(
math
.
E
,
_r
*
time
);
final
double
cosine
=
math
.
cos
(
_w
*
time
);
final
double
sine
=
math
.
sin
(
_w
*
time
);
return
power
*
(
_c2
*
_w
*
cosine
-
_c1
*
_w
*
sine
)
+
_r
*
power
*
(
_c2
*
sine
+
_c1
*
cosine
);
}
}
packages/newton/lib/src/tolerance.dart
0 → 100644
View file @
d5becff7
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of
newton
;
class
Tolerance
{
final
double
distance
;
final
double
time
;
final
double
velocity
;
const
Tolerance
({
this
.
distance
:
epsilonDefault
,
this
.
time
:
epsilonDefault
,
this
.
velocity
:
epsilonDefault
});
}
const
double
epsilonDefault
=
1
e
-
3
;
const
Tolerance
toleranceDefault
=
const
Tolerance
();
packages/newton/lib/src/utils.dart
0 → 100644
View file @
d5becff7
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of
newton
;
bool
_nearEqual
(
double
a
,
double
b
,
double
epsilon
)
=>
(
a
>
(
b
-
epsilon
))
&&
(
a
<
(
b
+
epsilon
));
bool
_nearZero
(
double
a
,
double
epsilon
)
=>
_nearEqual
(
a
,
0.0
,
epsilon
);
packages/newton/test/newton_test.dart
0 → 100644
View file @
d5becff7
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library
simple_physics
.
test
;
import
'package:test/test.dart'
;
import
'package:newton/newton.dart'
;
void
main
(
)
{
test
(
'test_friction'
,
()
{
var
friction
=
new
FrictionSimulation
(
0.3
,
100.0
,
400.0
);
friction
.
tolerance
=
const
Tolerance
(
velocity:
1.0
);
expect
(
friction
.
isDone
(
0.0
),
false
);
expect
(
friction
.
x
(
0.0
),
100
);
expect
(
friction
.
dx
(
0.0
),
400.0
);
expect
(
friction
.
x
(
1.0
)
>
330
&&
friction
.
x
(
1.0
)
<
335
,
true
);
expect
(
friction
.
dx
(
1.0
),
120.0
);
expect
(
friction
.
dx
(
2.0
),
36.0
);
expect
(
friction
.
dx
(
3.0
),
10.8
);
expect
(
friction
.
dx
(
4.0
)
<
3.5
,
true
);
expect
(
friction
.
isDone
(
5.0
),
true
);
expect
(
friction
.
x
(
5.0
)
>
431
&&
friction
.
x
(
5.0
)
<
432
,
true
);
});
test
(
'test_friction_through'
,
()
{
// Use a normal FrictionSimulation to generate start and end
// velocity and positions with drag = 0.025.
var
startPosition
=
10.0
;
var
startVelocity
=
600.0
;
var
f
=
new
FrictionSimulation
(
0.025
,
startPosition
,
startVelocity
);
var
endPosition
=
f
.
x
(
1.0
);
var
endVelocity
=
f
.
dx
(
1.0
);
expect
(
endPosition
,
greaterThan
(
startPosition
));
expect
(
endVelocity
,
lessThan
(
startVelocity
));
// Verify that that the "through" FrictionSimulation ends up at
// endPosition and endVelocity; implies that it computed the right
// value for _drag.
var
friction
=
new
FrictionSimulation
.
through
(
startPosition
,
endPosition
,
startVelocity
,
endVelocity
);
expect
(
friction
.
isDone
(
0.0
),
false
);
expect
(
friction
.
x
(
0.0
),
10.0
);
expect
(
friction
.
dx
(
0.0
),
600.0
);
double
epsilon
=
1
e
-
4
;
expect
(
friction
.
isDone
(
1.0
+
epsilon
),
true
);
expect
(
friction
.
x
(
1.0
),
closeTo
(
endPosition
,
epsilon
));
expect
(
friction
.
dx
(
1.0
),
closeTo
(
endVelocity
,
epsilon
));
// Same scenario as above except that the velocities are
// are negative.
startPosition
=
1000.0
;
startVelocity
=
-
500.0
;
f
=
new
FrictionSimulation
(
0.025
,
1000.0
,
-
500.0
);
endPosition
=
f
.
x
(
1.0
);
endVelocity
=
f
.
dx
(
1.0
);
expect
(
endPosition
,
lessThan
(
startPosition
));
expect
(
endVelocity
,
greaterThan
(
startVelocity
));
friction
=
new
FrictionSimulation
.
through
(
startPosition
,
endPosition
,
startVelocity
,
endVelocity
);
expect
(
friction
.
isDone
(
1.0
+
epsilon
),
true
);
expect
(
friction
.
x
(
1.0
),
closeTo
(
endPosition
,
epsilon
));
expect
(
friction
.
dx
(
1.0
),
closeTo
(
endVelocity
,
epsilon
));
});
test
(
'test_gravity'
,
()
{
var
gravity
=
new
GravitySimulation
(
200.0
,
100.0
,
600.0
,
0.0
);
expect
(
gravity
.
isDone
(
0.0
),
false
);
expect
(
gravity
.
x
(
0.0
),
100.0
);
expect
(
gravity
.
dx
(
0.0
),
0.0
);
// Starts at 100
expect
(
gravity
.
x
(
0.25
),
106.25
);
expect
(
gravity
.
x
(
0.50
),
125
);
expect
(
gravity
.
x
(
0.75
),
156.25
);
expect
(
gravity
.
x
(
1.00
),
200
);
expect
(
gravity
.
x
(
1.25
),
256.25
);
expect
(
gravity
.
x
(
1.50
),
325
);
expect
(
gravity
.
x
(
1.75
),
406.25
);
// Starts at 0.0
expect
(
gravity
.
dx
(
0.25
),
50.0
);
expect
(
gravity
.
dx
(
0.50
),
100
);
expect
(
gravity
.
dx
(
0.75
),
150.00
);
expect
(
gravity
.
dx
(
1.00
),
200.0
);
expect
(
gravity
.
dx
(
1.25
),
250.0
);
expect
(
gravity
.
dx
(
1.50
),
300
);
expect
(
gravity
.
dx
(
1.75
),
350
);
expect
(
gravity
.
isDone
(
2.5
),
true
);
expect
(
gravity
.
x
(
2.5
),
725
);
expect
(
gravity
.
dx
(
2.5
),
500.0
);
});
test
(
'spring_types'
,
()
{
var
crit
=
new
SpringSimulation
(
new
SpringDescription
.
withDampingRatio
(
mass:
1.0
,
springConstant:
100.0
),
0.0
,
300.0
,
0.0
);
expect
(
crit
.
type
,
SpringType
.
criticallyDamped
);
crit
=
new
SpringSimulation
(
new
SpringDescription
.
withDampingRatio
(
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
);
var
over
=
new
SpringSimulation
(
new
SpringDescription
.
withDampingRatio
(
mass:
1.0
,
springConstant:
100.0
,
ratio:
1.25
),
0.0
,
300.0
,
0.0
);
expect
(
over
.
type
,
SpringType
.
overDamped
);
// Just so we don't forget how to create a desc without the ratio.
var
other
=
new
SpringSimulation
(
new
SpringDescription
(
mass:
1.0
,
springConstant:
100.0
,
damping:
20.0
),
0.0
,
20.0
,
20.0
);
expect
(
other
.
type
,
SpringType
.
criticallyDamped
);
});
test
(
'crit_spring'
,
()
{
var
crit
=
new
SpringSimulation
(
new
SpringDescription
.
withDampingRatio
(
mass:
1.0
,
springConstant:
100.0
,
ratio:
1.0
),
0.0
,
500.0
,
0.0
);
crit
.
tolerance
=
const
Tolerance
(
distance:
0.01
,
velocity:
0.01
);
expect
(
crit
.
type
,
SpringType
.
criticallyDamped
);
expect
(
crit
.
isDone
(
0.0
),
false
);
expect
(
crit
.
x
(
0.0
),
0.0
);
expect
(
crit
.
dx
(
0.0
),
5000.0
);
expect
(
crit
.
x
(
0.25
).
floor
(),
458.0
);
expect
(
crit
.
x
(
0.50
).
floor
(),
496.0
);
expect
(
crit
.
x
(
0.75
).
floor
(),
499.0
);
expect
(
crit
.
dx
(
0.25
).
floor
(),
410
);
expect
(
crit
.
dx
(
0.50
).
floor
(),
33
);
expect
(
crit
.
dx
(
0.75
).
floor
(),
2
);
expect
(
crit
.
isDone
(
1.50
),
true
);
expect
(
crit
.
x
(
1.5
)
>
499.0
&&
crit
.
x
(
1.5
)
<
501.0
,
true
);
expect
(
crit
.
dx
(
1.5
)
<
0.1
,
true
/* basically within tolerance */
);
});
test
(
'overdamped_spring'
,
()
{
var
over
=
new
SpringSimulation
(
new
SpringDescription
.
withDampingRatio
(
mass:
1.0
,
springConstant:
100.0
,
ratio:
1.25
),
0.0
,
500.0
,
0.0
);
over
.
tolerance
=
const
Tolerance
(
distance:
0.01
,
velocity:
0.01
);
expect
(
over
.
type
,
SpringType
.
overDamped
);
expect
(
over
.
isDone
(
0.0
),
false
);
expect
(
over
.
x
(
0.0
),
0.0
);
expect
(
over
.
x
(
0.5
).
floor
(),
445.0
);
expect
(
over
.
x
(
1.0
).
floor
(),
495.0
);
expect
(
over
.
x
(
1.5
).
floor
(),
499.0
);
expect
(
over
.
dx
(
0.5
).
floor
(),
273.0
);
expect
(
over
.
dx
(
1.0
).
floor
(),
22.0
);
expect
(
over
.
dx
(
1.5
).
floor
(),
1.0
);
expect
(
over
.
isDone
(
3.0
),
true
);
});
test
(
'underdamped_spring'
,
()
{
var
under
=
new
SpringSimulation
(
new
SpringDescription
.
withDampingRatio
(
mass:
1.0
,
springConstant:
100.0
,
ratio:
0.25
),
0.0
,
300.0
,
0.0
);
expect
(
under
.
type
,
SpringType
.
underDamped
);
expect
(
under
.
isDone
(
0.0
),
false
);
// Overshot with negative velocity
expect
(
under
.
x
(
1.0
).
floor
(),
325
);
expect
(
under
.
dx
(
1.0
).
floor
(),
-
65
);
expect
(
under
.
dx
(
6.0
).
floor
(),
0.0
);
expect
(
under
.
x
(
6.0
).
floor
(),
299
);
expect
(
under
.
isDone
(
6.0
),
true
);
});
test
(
'test_kinetic_scroll'
,
()
{
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
);
scroll
.
tolerance
=
const
Tolerance
(
velocity:
0.5
,
distance:
0.1
);
expect
(
scroll
.
isDone
(
0.0
),
false
);
expect
(
scroll
.
isDone
(
0.5
),
false
);
// switch from friction to spring
expect
(
scroll
.
isDone
(
3.5
),
true
);
var
scroll2
=
new
ScrollSimulation
(
100.0
,
-
800.0
,
0.0
,
300.0
,
spring
,
0.3
);
scroll2
.
tolerance
=
const
Tolerance
(
velocity:
0.5
,
distance:
0.1
);
expect
(
scroll2
.
isDone
(
0.0
),
false
);
expect
(
scroll2
.
isDone
(
0.5
),
false
);
// switch from friction to spring
expect
(
scroll2
.
isDone
(
3.5
),
true
);
});
test
(
'scroll_with_inf_edge_ends'
,
()
{
var
spring
=
new
SpringDescription
.
withDampingRatio
(
mass:
1.0
,
springConstant:
50.0
,
ratio:
0.5
);
var
scroll
=
new
ScrollSimulation
(
100.0
,
400.0
,
0.0
,
double
.
INFINITY
,
spring
,
0.3
);
scroll
.
tolerance
=
const
Tolerance
(
velocity:
1.0
);
expect
(
scroll
.
isDone
(
0.0
),
false
);
expect
(
scroll
.
x
(
0.0
),
100
);
expect
(
scroll
.
dx
(
0.0
),
400.0
);
expect
(
scroll
.
x
(
1.0
)
>
330
&&
scroll
.
x
(
1.0
)
<
335
,
true
);
expect
(
scroll
.
dx
(
1.0
),
120.0
);
expect
(
scroll
.
dx
(
2.0
),
36.0
);
expect
(
scroll
.
dx
(
3.0
),
10.8
);
expect
(
scroll
.
dx
(
4.0
)
<
3.5
,
true
);
expect
(
scroll
.
isDone
(
5.0
),
true
);
expect
(
scroll
.
x
(
5.0
)
>
431
&&
scroll
.
x
(
5.0
)
<
432
,
true
);
// We should never switch
expect
(
scroll
.
currentIntervalOffset
,
0.0
);
});
test
(
'over/under scroll spring'
,
()
{
var
spring
=
new
SpringDescription
.
withDampingRatio
(
mass:
1.0
,
springConstant:
170.0
,
ratio:
1.1
);
var
scroll
=
new
ScrollSimulation
(
500.0
,
-
7500.0
,
0.0
,
1000.0
,
spring
,
0.025
);
scroll
.
tolerance
=
new
Tolerance
(
velocity:
45.0
,
distance:
1.5
);
expect
(
scroll
.
isDone
(
0.0
),
false
);
expect
(
scroll
.
x
(
0.0
),
closeTo
(
500.0
,
.
0001
));
expect
(
scroll
.
dx
(
0.0
),
closeTo
(-
7500.0
,
.
0001
));
expect
(
scroll
.
isDone
(
0.025
),
false
);
expect
(
scroll
.
x
(
0.025
),
closeTo
(
320.0
,
1.0
));
expect
(
scroll
.
dx
(
0.25
),
closeTo
(-
2982
,
1.0
));
expect
(
scroll
.
isDone
(
2.0
),
true
);
expect
(
scroll
.
x
(
2.0
),
0.0
);
expect
(
scroll
.
dx
(
2.0
),
closeTo
(
0.0
,
45.0
));
});
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment