mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
parent
f3561d8035
commit
d9061bc96e
@ -5,16 +5,12 @@
|
|||||||
/// Simple Physics Simulations for Dart. Springs, friction, gravity, etc.
|
/// Simple Physics Simulations for Dart. Springs, friction, gravity, etc.
|
||||||
library newton;
|
library newton;
|
||||||
|
|
||||||
import 'dart:math' as math;
|
export 'src/clamped_simulation.dart';
|
||||||
|
export 'src/friction_simulation.dart';
|
||||||
part 'src/simulation.dart';
|
export 'src/gravity_simulation.dart';
|
||||||
part 'src/simulation_group.dart';
|
export 'src/scroll_simulation.dart';
|
||||||
part 'src/tolerance.dart';
|
export 'src/simulation_group.dart';
|
||||||
part 'src/utils.dart';
|
export 'src/simulation.dart';
|
||||||
|
export 'src/spring_simulation.dart';
|
||||||
part 'src/clamped_simulation.dart';
|
export 'src/tolerance.dart';
|
||||||
part 'src/friction_simulation.dart';
|
export 'src/utils.dart';
|
||||||
part 'src/gravity_simulation.dart';
|
|
||||||
part 'src/scroll_simulation.dart';
|
|
||||||
part 'src/spring_simulation.dart';
|
|
||||||
part 'src/spring_solution.dart';
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
part of newton;
|
import 'simulation.dart';
|
||||||
|
|
||||||
class ClampedSimulation extends Simulation {
|
class ClampedSimulation extends Simulation {
|
||||||
ClampedSimulation(this.simulation, {
|
ClampedSimulation(this.simulation, {
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
|
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
part of newton;
|
import 'dart:math' as math;
|
||||||
|
|
||||||
|
import 'simulation.dart';
|
||||||
|
import 'tolerance.dart';
|
||||||
|
|
||||||
class FrictionSimulation extends Simulation {
|
class FrictionSimulation extends Simulation {
|
||||||
final double _drag;
|
final double _drag;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
|
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
part of newton;
|
import 'simulation.dart';
|
||||||
|
|
||||||
class GravitySimulation extends Simulation {
|
class GravitySimulation extends Simulation {
|
||||||
final double _x;
|
final double _x;
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
|
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
part of newton;
|
import 'friction_simulation.dart';
|
||||||
|
import 'simulation_group.dart';
|
||||||
|
import 'simulation.dart';
|
||||||
|
import 'spring_simulation.dart';
|
||||||
|
|
||||||
/// Simulates kinetic scrolling behavior between a leading and trailing
|
/// Simulates kinetic scrolling behavior between a leading and trailing
|
||||||
/// boundary. Friction is applied within the extends and a spring action applied
|
/// boundary. Friction is applied within the extends and a spring action applied
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
|
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
part of newton;
|
import 'tolerance.dart';
|
||||||
|
|
||||||
abstract class Simulatable {
|
abstract class Simulatable {
|
||||||
/// The current position of the object in the simulation
|
/// The current position of the object in the simulation
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
|
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
part of newton;
|
import 'simulation.dart';
|
||||||
|
import 'tolerance.dart';
|
||||||
|
import 'utils.dart';
|
||||||
|
|
||||||
/// The abstract base class for all composite simulations. Concrete subclasses
|
/// The abstract base class for all composite simulations. Concrete subclasses
|
||||||
/// must implement the appropriate methods to select the appropriate simulation
|
/// must implement the appropriate methods to select the appropriate simulation
|
||||||
@ -46,7 +48,7 @@ abstract class SimulationGroup extends Simulation {
|
|||||||
|
|
||||||
double _lastStep = -1.0;
|
double _lastStep = -1.0;
|
||||||
void _stepIfNecessary(double time) {
|
void _stepIfNecessary(double time) {
|
||||||
if (_nearEqual(_lastStep, time, toleranceDefault.time)) {
|
if (nearEqual(_lastStep, time, toleranceDefault.time)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,124 @@
|
|||||||
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
|
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
part of newton;
|
import 'dart:math' as math;
|
||||||
|
|
||||||
|
import 'simulation.dart';
|
||||||
|
import 'utils.dart';
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class SpringDescription {
|
class SpringDescription {
|
||||||
/// The mass of the spring (m)
|
/// The mass of the spring (m)
|
||||||
@ -58,8 +174,8 @@ class SpringSimulation extends Simulation {
|
|||||||
double dx(double time) => _solution.dx(time);
|
double dx(double time) => _solution.dx(time);
|
||||||
|
|
||||||
bool isDone(double time) {
|
bool isDone(double time) {
|
||||||
return _nearZero(_solution.x(time), tolerance.distance) &&
|
return nearZero(_solution.x(time), tolerance.distance) &&
|
||||||
_nearZero(_solution.dx(time), tolerance.velocity);
|
nearZero(_solution.dx(time), tolerance.velocity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,118 +0,0 @@
|
|||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +1,7 @@
|
|||||||
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
|
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
part of newton;
|
|
||||||
|
|
||||||
class Tolerance {
|
class Tolerance {
|
||||||
final double distance;
|
final double distance;
|
||||||
final double time;
|
final double time;
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
|
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
part of newton;
|
bool nearEqual(double a, double b, double epsilon) =>
|
||||||
|
|
||||||
bool _nearEqual(double a, double b, double epsilon) =>
|
|
||||||
(a > (b - epsilon)) && (a < (b + epsilon));
|
(a > (b - epsilon)) && (a < (b + epsilon));
|
||||||
|
|
||||||
bool _nearZero(double a, double epsilon) => _nearEqual(a, 0.0, epsilon);
|
bool nearZero(double a, double epsilon) => nearEqual(a, 0.0, epsilon);
|
||||||
|
Loading…
Reference in New Issue
Block a user