🪶 Flutterで学ぶ:ニュートンの運動方程式を「動かして」理解するメモ
Flutterのアニメーションやゲーム的表現に生かすために、
物理の考え方から実装までをわかりやすく整理します。
🌍 1. ニュートンの運動方程式とは
基本形はこれです:
F = m a
- F:力(Force)
- m:質量(Mass)
- a:加速度(Acceleration)
この式は、「力が加わると、その向きに加速度が生じる」という
運動のルールを定量的に表したものです。
⚙️ 2. Flutter的に言うと「位置を時間で更新する仕組み」
アニメーションや物理演算を扱うとき、私たちは
「時間経過によって位置を更新する」処理を書きます。
ニュートンの式を時間ステップに離散化すると:
// Flutterでの擬似コード
v += a * dt; // 速度を更新
x += v * dt; // 位置を更新
これはつまり、
「加速度を積分すると速度になり、
速度を積分すると位置になる」
という流れをそのままコード化しています。
FlutterのTickerやAnimationControllerは、
内部的にこの「dt(経過時間)」を毎フレーム渡してくれます。
🧮 3. 実例:重力で落ちるボール
では、Flutterで「重力に従って落ちる物体」を実装してみましょう。
import 'package:flutter/material.dart';
import 'dart:math';
class GravityBall extends StatefulWidget {
const GravityBall({super.key});
State<GravityBall> createState() => _GravityBallState();
}
class _GravityBallState extends State<GravityBall>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
double y = 0.0; // 位置
double v = 0.0; // 速度
double g = 9.8; // 加速度(重力加速度)
void initState() {
super.initState();
_controller =
AnimationController(vsync: this, duration: const Duration(days: 1))
..addListener(_update)
..forward();
}
void _update() {
const dt = 1 / 60; // 1フレーム ≒ 1/60秒
v += g * dt; // 加速度から速度を更新
y += v * dt * 100; // 速度から位置を更新(ピクセル換算)
// 画面下で跳ね返る
if (y > 500) {
y = 500;
v = -v * 0.8; // 反発係数で減速
}
setState(() {});
}
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blue[50],
body: Center(
child: CustomPaint(
size: const Size(300, 600),
painter: BallPainter(y),
),
),
);
}
void dispose() {
_controller.dispose();
super.dispose();
}
}
class BallPainter extends CustomPainter {
final double y;
BallPainter(this.y);
void paint(Canvas canvas, Size size) {
final paint = Paint()..color = Colors.deepPurple;
canvas.drawCircle(Offset(size.width / 2, y), 20, paint);
}
bool shouldRepaint(covariant BallPainter oldDelegate) => true;
}
これだけで、「F = ma」の世界をFlutter上で再現できます。
g が「力による加速度」
v が「加速度を積分した速度」
y が「速度を積分した位置」
🌊 4. 抵抗や浮力を入れると「現実的」になる
物理式を少し拡張して、空気や水の中を落ちる表現もできます。
a = (mg - ρgV - 0.5ρCdAv|v|) / m
この式の意味:
項 意味
mg 重力
ρgV 浮力(上向き)
0.5ρCdAv v
これをFlutterに落とし込むと:
a = (m * g - rho * g * V - 0.5 * rho * Cd * A * v.abs() * v) / m;
このように、環境変数(ρ, Cd, Aなど)を調整することで挙動が変化します。
アプリによっては「水中モード」「空気中モード」として切り替えても面白いですね。
🧠 5. Flutterで「力」をどう表現するか
① ユーザー操作を力に変換
タップやドラッグを「外力」として扱うとインタラクティブにできます。
onPanUpdate: (details) {
final dragForce = details.delta.dy * 0.5;
v += dragForce; // 力を速度に加算
}
② 環境パラメータで世界観を作る
物理ゲームやアートアプリでは、以下をチューニングするだけで雰囲気が変わります。
パラメータ 意味 効果例
g 重力 小さくするとスローに落下
Cd 抵抗係数 大きいと空気中のようにゆっくり
反発係数 跳ね返りの強さ 弾む・沈むの表現
📱 6. Flutterでの物理表現の広がり
概念 Flutterでの実装ヒント
加速度 AnimationController + 物理計算
摩擦・抵抗 v *= 0.98 のような減速係数
バネ運動 Hookeの法則 F = -kx を追加
複数物体 List<Ball> をループして描画
これらを組み合わせると、2D物理エンジンの簡易版ができます。
🧩 7. 学びのまとめ
観点 内容
物理 F = ma(力が加速度を生む)
実装 v += a * dt; → x += v * dt;
拡張 抵抗・浮力・反発などを力の項として追加
Flutter TickerやCustomPainterで表現可能
Discussion