Skip to content

Instantly share code, notes, and snippets.

@andretietz
Last active May 26, 2019 17:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andretietz/d18d74b44ba21d6c61b8b7dde6314ac6 to your computer and use it in GitHub Desktop.
Save andretietz/d18d74b44ba21d6c61b8b7dde6314ac6 to your computer and use it in GitHub Desktop.
Flutter: Rubics Cube
import 'dart:math';
import 'package:flutter/widgets.dart';
import 'package:vector_math/vector_math_64.dart';
class TestCubeWidget extends StatelessWidget {
static const _angle = pi / 4;
final double _height;
final double _width;
const TestCubeWidget({double width = 150.0, double height = 150.0})
: this._width = width,
this._height = height;
@override
Widget build(BuildContext context) {
List<int> state = List(54);
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 9; j++) {
state[i * 9 + j] = i + 1;
}
}
return Container(
width: _width,
height: _height,
child: CustomPaint(
foregroundPainter: _CubePainter(Size(_width, _height), state, _angle, 2, [
Color.fromARGB(255, 0, 255, 0), // green => 1 -> F
Color.fromARGB(255, 255, 255, 0), // yellow => 2 -> U
Color.fromARGB(255, 255, 165, 0), // orange => 3 -> R
Color.fromARGB(255, 255, 0, 0), // red => 4 -> L
Color.fromARGB(255, 255, 255, 255), // white => 5 -> D
Color.fromARGB(255, 0, 0, 255), // blue => 6 -> B
])),
);
}
}
class _CubePainter extends CustomPainter {
final Paint _paint = Paint();
final List<Color> _colors;
List<int> _state;
final _turn;
List<Rect> _side;
List<Matrix4> _positions;
_CubePainter(Size size, this._state, this._turn, [double padding = 2, List<Color> colors]) : _colors = colors {
var cubieSize = (((size.width > size.height) ? size.height : size.width) / 3 * (1 / 2)) - padding;
var outer = (1.5 * cubieSize + 2 * padding);
var inner = (0.5 * cubieSize);
var center = (0.5 * cubieSize + 2 * padding);
var end = (1.5 * cubieSize + 3 * padding);
_side = <Rect>[
Rect.fromLTRB(-outer, -outer, -center, -center), // lefter upper
Rect.fromLTRB(-inner, -outer, inner, -center), // center upper
Rect.fromLTRB(center, -outer, outer, -center), // right upper
Rect.fromLTRB(-outer, -inner, -center, inner), // lefter center
Rect.fromLTRB(-inner, -inner, inner, inner), // center center
Rect.fromLTRB(center, -inner, outer, inner), // right center
Rect.fromLTRB(-outer, center, -center, outer), // lefter bottom
Rect.fromLTRB(-inner, center, inner, outer), // center bottom
Rect.fromLTRB(center, center, outer, outer), // right bottom
];
_positions = [
Matrix4.identity()..translate(0.0, 0.0, -end),
Matrix4.identity()
..rotate(Vector3(1, 0, 0), -pi / 2)
..translate(0.0, 0.0, -end),
Matrix4.identity()
..rotate(Vector3(0, 1, 0), -pi / 2)
..translate(0.0, 0.0, -end),
Matrix4.identity()
..rotate(Vector3(0, 1, 0), pi / 2)
..translate(0.0, 0.0, -end),
Matrix4.identity()
..rotate(Vector3(1, 0, 0), pi / 2)
..translate(0.0, 0.0, -end),
Matrix4.identity()
..rotate(Vector3(0, 1, 0), pi)
..translate(0.0, 0.0, -end)
];
}
@override
void paint(Canvas canvas, Size size) {
var matrix = Matrix4.identity()
..setEntry(3, 2, 0.002)
..rotate(Vector3(1, 1, 0), _turn);
List<int> sortedKeys = createZOrder(matrix);
for (int i in sortedKeys) {
var tmp = matrix.multiplied(_positions[i]);
canvas.save();
canvas.transform(tmp.storage);
for (int j = 0; j < 9; j++) {
_paint.color = (_colors != null) ? _colors[_state[i * 9 + j] - 1] : Color.fromARGB(0xFF, 0x00, 0x0, 0x0);
canvas.drawRect(_side[j], _paint);
}
canvas.restore();
}
}
List<int> createZOrder(Matrix4 matrix) {
Map<int, double> renderOrder = Map();
Vector3 pos = Vector3.zero();
for (int i = 0; i < 6; i++) {
renderOrder[i] = 0.0;
var tmp = matrix.multiplied(_positions[i]);
for (int j = 0; j < 9; j++) {
pos.x = _side[j].center.dx;
pos.y = _side[j].center.dy;
pos.z = 0.0;
var t = tmp.transform3(pos).z;
if (t > renderOrder[i]) renderOrder[i] = t;
}
}
return renderOrder.keys.toList(growable: false)..sort((a, b) => renderOrder[b].compareTo(renderOrder[a]));
}
@override
bool shouldRepaint(_CubePainter oldDelegate) {
return oldDelegate._state != this._state;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment