The second day of the seven-day tour ----2018-12-17---- The weather was fine

Zero foreword:

Yesterday I talked about the basic project of Flutter, introduced the Dart language, and simply drew a picture on Canvas

I was going to have a look at the built-in controls today, but since I drew all the pictures yesterday, I will not animate them today, but today I will try to streamline the animation. By the way, I will copy the Android-Java particle movements into the Flutter-Dart and finally achieve a particle clock. See the Java version for more details: So this is going to be fun. Seeds, drinks, peanuts. Here we go

First pick a few map town building

Sports box Smash the ball
Star and mans Star expansion moving

First, entry-level animation:The growth of the pentacle


1. Follow the flute

Following yesterday’s Flutter initial project, let’s write one ourselves

I like to subcontract,Javaer’s good habits. At least the logic is clear, and the division of work is clear. I created a Pager package with AnimaPage on the main page. I don’t know what StatefulWidget is yet, but I’ll just follow the script of the original project. The custom AnimaView in the drawing area is intended to animate the circumcircular radius R of the pentagram

import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:toly/view/anima_view.dart'; class AnimaPage extends StatefulWidget { @override _AnimaPageState createState() => _AnimaPageState(); } class _AnimaPageState extends State<AnimaPage>{ double _R = 25; @override Widget build(BuildContext context) {return Scaffold(appBar: appBar (title: Text(" Context "),), Body: CustomPaint(Painter: AnimaView(context, _R),), floatingActionButton: FloatingActionButton( onPressed: () { }, tooltip: 'Increment', child: Icon(Icons.add), ), ); }}Copy the code

2.AnimaView implementation:

The path of the n-angular star was encapsulated on the first day, but no, you can go and look at it

import 'dart:ui'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:toly/helper/common_path.dart'; import 'package:toly/helper/help_view.dart'; class AnimaView extends CustomPainter { Paint mPaint; BuildContext context; double _R; AnimaView(this.context, double r) { mPaint = new Paint(); mPaint.color = Colors.deepOrange; _R = r; } @override void paint(Canvas canvas, Size size) { var winSize = MediaQuery.of(context).size; drawGrid(canvas, winSize); drawCoo(canvas, new Size(160, 320), winSize); canvas.translate(160, 320); canvas.drawPath(nStarPath(5, _R, 50), mPaint); } @override bool shouldRepaint(CustomPainter oldDelegate) { return true; }}Copy the code

3. Get your data moving

Now everything is ready. All that is needed is for the east wind to blow the value of R. Let’s welcome the Animation

Fill with vsync need SingleTickerProviderStateMixi Tween: between animation – here: Between 25.0, ~ 150.0, and within 2000ms, the change is uniform (PS: due to the different program running, it is not absolutely uniform, but on the whole is uniform).. : is a cascade operation, equivalent to using this object again, here.. Animation.

class AnimaPage extends StatefulWidget { @override _AnimaPageState createState() => _AnimaPageState(); } class _AnimaPageState extends State<AnimaPage> with SingleTickerProviderStateMixin { AnimationController controller; Animation<double> animation; double _R = 25; @override void initState() { super.initState(); / / / / objects created AnimationController | - will prevent vsync screen outside animated UI is out of the current screen (animation) unnecessary resource consumption controller = AnimationController (duration: const Duration(milliseconds: 2000), vsync: this); Animation = Tween(begin: 25.0, end: 150.0). Animate (Controller).. addListener(() { setState(() { _R = animation.value; }); }); } @override void dispose() { super.dispose(); controller.dispose(); } @override Widget build(BuildContext context) {return Scaffold(appBar: appBar (title: Text(" Context "),), Body: CustomPaint(Painter: AnimaView(context, _R),), floatingActionButton: FloatingActionButton( onPressed: () { controller.forward(); }, tooltip: 'Increment', child: Icon(icons.add),),); }}Copy the code

So the simplest animation is moving


4. Let’s get this straight

Turn over the source code, feel the whole animation system is not very complex

Routine is: Animatable using the animate method, an Animation package, to form a more powerful Animation as to their son n, namely the data processing is different, the effect of the different, routines know, all right


You can see that there aren’t as many apis as you might think, so don’t be afraid


Ii. Entry-level Animation:The bloom of the pentacle

So we’re Tween, and we’re only moving once, and then we’re going to have a continuous uneven animation

Constant reciprocation Custom curve bounceInOut

1. Reciprocating motion
1.1: Motion state

You can imagine a person running on a range of digital tracks:

Enum AnimationStatus {/// The animation is stopped at The beginning to dismiss,// The animation is running From beginning to end forward,// motion iN /// The animation is running backwards, from end to beginning reverse, // The animation is stopped at The end of The completed,// The animation is stopped at The end of The completed,}Copy the code

1.2: Status monitoring

AddStatusListener: You can listen to the current state of motion: just let it run out, and then run back

Animation = Tween(begin: 25.0, end: 150.0). Animate (Controller).. addListener(() { setState(() { _R = animation.value; }); }).. addStatusListener((status) { if (status == AnimationStatus.completed) { controller.reverse(); } else if (status == AnimationStatus.dismissed) { controller.forward(); }});Copy the code

2. Speed

Just like athletes speed running, it feels like a buff in the game, which was originally a constant Animation

The buff class is Animatable, and its subclass has a CurveTween:

Animation = Tween(begin: 25.0, end: 150.0). Animate (CurveTween(curve: Curves. BounceInOut). Animate (controller))Copy the code

That’s it. There are several built-in transmissions in Curves. Just install the original animation


3. Custom speed change curve
3.1: Trace the source code
-- -- -- - > [CurveTween] -- -- -- -- -- -- -- -- -- control only one parameter Curve -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the class CurveTween extends Animatable < double > {/ / / Creates a curve tween. /// /// The [curve] argument must not be null. CurveTween({ @required this.curve }) : assert(curve ! = null); /// The curve to use when transforming the value of the animation. Curve curve; -- -- -- - > [Curve] -- -- -- -- -- -- -- -- abstract, looking for a son to -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- @immutable abstract class Curve {-- -- -- - > [Curve] -- -- -- -- -- -- -- -- four and the Curve of the structure, -------------------- class Cubic extends Curve {/// Creates a Cubic Curve. /// /// Rather than creating a new instance, consider using one of the common /// cubic curves in [Curves]. /// /// The [a], [b], [c], and [d] arguments must not be null. const Cubic(this.a, this.b, this.c, this.d)Copy the code

3.2: Chrome gadgets

As a front-end hobbyist, it’s useful to have a little thing in Chrome,

Curve generation, with its own preview, is simply accidental. (Remember that nuggets avatar can be translated.)


3.3: use:
Animation = Tween(begin: 25.0, end: 150.0). Animate (CurveTween(curve: Cubic(0.96, 0.13, 0.1, 1.2)). Animate (controller))Copy the code

Ok, that’s pretty much it. Did you get it?


Iii. Primary Animation:The birth of the Sun

Red sun Star and Yang
1. Red Sun: Int animation

I got it. These dynamics change the number of sharp angles on an N-pointed star and see what happens

1.1: AnimaPage defines sharp animations
Animation<int> numAnima; Int num = 5; Controller = AnimationController(duration: const duration (milliseconds: 2000), vsync: this); numAnima = IntTween(begin: 5, end: 220).animate(controller) .. addListener(() { setState(() { _num = numAnima.value; // Set properties to refresh the interface}); }).. addStatusListener((status) { if (status == AnimationStatus.completed) { controller.reverse(); } else if (status == AnimationStatus.dismissed) { controller.forward(); }});Copy the code

1.2: Adding parameters to AnimaView
int _num; AnimaView(this.context, {double R, int num, Color color}) { _num = num; } canvas. DrawPath (nStarPath(_num, 100, 50), mPaint);Copy the code

2. Star and Sun: Color animation

ColorTween is the same as adding a buff of a color change, so let’s add it to the parameter and do the same thing, just color the brush

colorAnima =
        ColorTween(begin: Colors.yellow, end: Colors.red).animate(controller)
          ..addListener(() {
            setState(() {
              _color = colorAnima.value;
            });
          })
          ..addStatusListener((status) {
            if (status == AnimationStatus.completed) {
              controller.reverse();
            } else if (status == AnimationStatus.dismissed) {
              controller.forward();
            }
          });
Copy the code

3. Other effects

Play by yourself and change some properties

Star and mans Star expansion moving

Star and awn: fixed five-pointed star inner circle radius, the radius of the circle becomes larger, the number of angles becomes more, the color becomes red star expansion: five-pointed star inner circle radius is half of the circle, the radius of the circle becomes larger, the number of angles becomes more, the color becomes red

All right, that's it. Let's get down to business

4. Particle motion

No matter what language you can only have particle animation if you can simulate time flow

The basics of particle animation are detailed in Android Native Drawing to get you into the motion of A View and the idea is common to all languages, not just Java, if you’re interested in it

1. Let’s cut to the chaseSports boxBesides,

A sports box is an animation of the ball bouncing around inside the box, like this

1.1: New file:run_ball_view.dart----->RunBallView + Ball

Let me write down the physical class of the ball

class Ball { double aX; // Double aY; // Acceleration Y double vX; // speed X double vY; // speed Y double x; // double y; // select * from Y where Y = 1; // Double r; X, y, this.color, this.r, this.ax, this.ay, this.vx, this.vy}); }Copy the code

1.2: Artboard ready
class RunBallView extends CustomPainter { Paint mPaint; BuildContext context; Ball _ball; Rect _limit; RunBallView(this.context, Ball ball, Rect limit) { mPaint = new Paint(); _ball = ball; _limit = limit; } @override void paint(Canvas canvas, Size size) { var winSize = MediaQuery.of(context).size; canvas.translate(160, 320); mPaint.color = Color.fromARGB(148, 198, 246, 248); canvas.drawRect(_limit, mPaint); canvas.save(); drawBall(canvas, _ball); canvas.restore(); } @override bool shouldRepaint(CustomPainter oldDelegate) { return true; Void drawBall(Canvas Canvas, Ball Ball) {mPaint. Color = Ball. Color; canvas.drawCircle(Offset(ball.x, ball.y), ball.r, mPaint); }}Copy the code

1.3: Get to know the Rect object

This is the field that we need

var limit = Rect.fromLTRB(-140, -100, 140, 100); print("width:${limit.width}"); print("height:${limit.height}"); print("left:${limit.left}"); print("top:${limit.top}"); print("right:${limit.right}"); print("bottom:${limit.bottom}"); I/flutter (28755): width:280.0 I/flutter (28755): height:200.0 I/flutter (28755): left:-140.0 I/flutter (28755): Top :-100.0 I/flutter (28755): Right :140.0 I/flutter (28755): bottom:100.0Copy the code

1.4 new file:run_ball_pager.dart---->RunBallPage

Only one time stream is needed, and a single AnimationController is sufficient

class RunBallPage extends StatefulWidget { @override _RunBallPageState createState() => _RunBallPageState(); } class _RunBallPageState extends State<RunBallPage> with SingleTickerProviderStateMixin { AnimationController controller; Ball _ball; var _limit = Rect.fromLTRB(-140, -100, 140, 100); @override void initState() {super.initState(); // Initialize the Ball _ball = Ball(x: 0, y: 0, color: color. blue, r: 10, aX: 0, aY: 0, vX: 0, vY: 2); / / / / objects created AnimationController | - will prevent vsync screen outside animated UI is out of the current screen (animation) unnecessary resource consumption controller = AnimationController (duration: const Duration(milliseconds: 200000), vsync: this); controller.addListener(() { updateBall(); // Update the ball setState(() {}); }); controller.addStatusListener((status) { if (status == AnimationStatus.completed) { controller.reverse(); } else if (status == AnimationStatus.dismissed) { controller.forward(); }}); } @override void dispose() { super.dispose(); controller.dispose(); } @override Widget build(BuildContext context) {return Scaffold(appBar: appBar (title: Text(" Picture "),), Body: CustomPaint(Painter: RunBallView(context, _ball, _LIMIT),), floatingActionButton: FloatingActionButton( onPressed: () { controller.forward(); }, tooltip: 'Increment', child: Icon(icons.add),),); Void updateBall() {}}Copy the code

And then the static ball is done


1.5: Update new ball position, render view:RunBallPage#updateBall

// updateBall position void updateBall() {// kinematics formula _ball.x += _ball.vx; _ball.y += _ball.vY; _ball.vX += _ball.aX; _ball.vY += _ball.aY; If (_ball.y > _limit.bottom-_ball.r) {_ball.y = _limit.bottom-_ball.r; _ball.vY = -_ball.vY; _ball.color=randomRGB(); If (_ball.y < _limit.top + _ball.r) {_ball.y = _limit.top + _ball.r; _ball.vY = -_ball.vY; _ball.color=randomRGB(); // Random color after collision}}Copy the code

1.6: The realization of sports box

_ball = Ball(x: 0, y: 0, color: color. blue, r: 10, aX: 0, aY: 0.1, vX: 2, vY: -2); // updateBall position void updateBall() {// kinematics formula _ball.x += _ball.vx; _ball.y += _ball.vY; _ball.vX += _ball.aX; _ball.vY += _ball.aY; If (_ball.y > _limit.bottom-_ball.r) {_ball.y = _limit.bottom-_ball.r; _ball.vY = -_ball.vY; _ball.color=randomRGB(); If (_ball.y < _limit.top + _ball.r) {_ball.y = _limit.top + _ball.r; _ball.vY = -_ball.vY; _ball.color=randomRGB(); If (_ball.x < _limit.left + _ball.r) {_ball.x = _limit.left + _ball.r; _ball.vX = -_ball.vX; _ball.color=randomRGB(); If (_ball.x > _limit.right-_ball.r) {_ball.x = _limit.right-_ball.r; _ball.vX= -_ball.vX; _ball.color=randomRGB(); // Random color after collision}}Copy the code

2. Motion of particles

The idea is to load the ball with a List. When you collide, create a ball with the opposite direction and half the radius and add it to the set

And halve the radius of the current sphere, which works pretty well, and doesn’t take much trouble to achieve. Android – Java version is visible


2.1: Changes:RunBallPage

If the radius is less than 0.3, remove it. In order not to allow the ball to grow indefinitely, if the radius is less than 0.3, the ball is basically stuck

Of course, you can also customize the timing of removal

var _balls = List<Ball>(); Var ball = ball (x: 0, y: 0, color: color. blue, r: 40, aX: 0.05, aY: 0.1, vX: 3, vY: -3); _balls.add(ball); For (int I = 0; i < _balls.length; i++) { var ball = _balls[i]; If (ball.r < 0.3) {// remove _balls.removeat (I); } // The kinematics formula ball-.x += ball-.vx; ball.y += ball.vY; ball.vX += ball.aX; ball.vY += ball.aY; If (ball.y > _limit.bottom) {var newBall = ball.fromball (ball); newBall.r = newBall.r / 2; newBall.vX = -newBall.vX; newBall.vY = -newBall.vY; _balls.add(newBall); ball.r = ball.r / 2; ball.y = _limit.bottom; ball.vY = -ball.vY; ball.color = randomRGB(); If (ball.y < _limit.top) {ball.y = _limit.top; ball.vY = -ball.vY; ball.color = randomRGB(); If (ball.x < _limite.left) {ball.x = _limite.left; ball.vX = -ball.vX; ball.color = randomRGB(); If (ball.x > _limit.right) {var newBall = ball.fromball (ball); newBall.r = newBall.r / 2; newBall.vX = -newBall.vX; newBall.vY = -newBall.vY; _balls.add(newBall); ball.r = ball.r / 2; ball.x = _limit.right; ball.vX = -ball.vX; ball.color = randomRGB(); }}} body: CustomPaint(Painter: RunBallView(context, _balls, _limit),)Copy the code

2.2: When drawing the ball:RunBallView:

I’m just going to draw all the balls

// Copy a small Ball. FromBall (Ball Ball) {this.x = ball.x; this.y = ball.y; this.color = ball.color; this.r = ball.r; this.aX = ball.aX; this.aY = ball.aY; this.vX = ball.vX; this.vY = ball.vY; } / / -- -- -- -- -- - in the paint method -- -- -- -- -- -- -- -- -- -- - _balls. ForEach ((ball) {drawBall (canvas, ball); });Copy the code

So finished, is not as complex as imagined


Particle clock

This is not a detailed analysis of the Java version of the analysis has been very detailed, directly on the code (basically Java translation version)

This effect is done on a new page, with the Dart version of the Digit 3D array attached at the end of the text

1. Render numbers

@param canvas */ void renderDigit(int num, canvas canvas) {if (num > 10) {return; } for (int i = 0; i < digit[num].length; i++) { for (int j = 0; j < digit[num][j].length; j++) { if (digit[num][i][j] == 1) { canvas.save(); double rX = j * 2 * (_radius + 1) + (_radius + 1); Double rY = I * 2 * (_radius + 1) + (_radius + 1); // Canvas. Translate (rX, rY); // Canvas. mPaint.color = Colors.blue; canvas.drawPath(mStarPath, mPaint); canvas.restore(); }}}}Copy the code

2. Paint on the canvas1994
canvas.save();
renderDigit(1, canvas);
canvas.translate(80, 0);
renderDigit(9, canvas);
canvas.translate(80, 0);
renderDigit(9, canvas);
canvas.translate(80, 0);
renderDigit(4, canvas);
canvas.restore();
Copy the code

3. Draw the time

3.1: Simple time acquisition
DateTime now = new DateTime.now(); var hour = now.hour; var second = now.second; var minute = now.minute; print("hour$hour"); //15 print("second$second"); //57 print("minute$minute"); / / 27Copy the code

3.2: Drawing time
RenderDigit (_now.hour ~/ 10, canvas); canvas.translate(19 * _radius, 0); renderDigit(_now.hour % 10, canvas); // : canvas.translate(19 * _radius, 0); renderDigit(10, canvas); // Canvas. Translate (11 * _radius, 0); renderDigit(_now.minute ~/ 10, canvas); canvas.translate(19 * _radius, 0); renderDigit(_now.minute % 10, canvas); // : canvas.translate(18 * _radius, 0); renderDigit(10, canvas); // second canvas.translate(11 * _radius, 0); renderDigit(_now.second ~/ 10, canvas); canvas.translate(19 * _radius, 0); renderDigit(_now.second % 10, canvas);Copy the code

3.3: Animation


4. Add ball

The method is basically the Java version to change some, here do not analyze, you can see the Java version of the analysis, basically the same

Var currTime = new datetime.now (); var tagOfBall = new DateTime.now().millisecondsSinceEpoch; var _balls = new List<Ball>(); // ClockView(this.context) {mPaint = new Paint(); mStarPath = nStarPath(5, _radius, _radius / 2); _now = new DateTime.now(); addBallsChanged(); updateBalls(); } / / void addBallsChanged() {var now = new datetime.now (); if (currTime.second ! = now.second) {// if ((currtime.hour ~/ 10)! = (now.hour ~/ 10)) { addBalls((-17 * 5 - 11 * 2) * _radius.toInt(), currTime.hour ~/ 10); } if ((currTime.hour % 10) ! = (now.hour % 10)) { addBalls((-17 * 4 - 11 * 2) * _radius.toInt(), currTime.hour % 10); } if ((currTime.minute ~/ 10) ! = (now.minute ~/ 10)) { addBalls((-18 * 3 - 11) * _radius.toInt(), currTime.minute ~/ 10); } if ((currTime.minute % 10) ! = (now.minute % 10)) { addBalls((-18 * 2 - 11) * _radius.toInt(), currTime.minute % 10); } if ((currTime.second ~/ 10) ! = (now.second ~/ 10)) { addBalls(-18 * _radius.toInt(), currTime.second ~/ 10); } if ((currTime.second % 10) ! = (now.second % 10)) { addBalls(0, currTime.second % 10); currTime = now; AddBalls (int offsetX, int num) {Random Random = new Random(); for (int i = 0; i < digit[num].length; i++) { for (int j = 0; j < digit[num][i].length; j++) { if (digit[num][i][j] == 1) { Ball ball = new Ball(); Ball. AY = 0.1; ball.vX = pow(-1, random.nextInt(1000)) * 6 * random.nextDouble(); ball.vY = 4 * random.nextDouble(); ball.x = offsetX + j * 2 * (_radius + 1) + (_radius + 1); Y = I * 2 * (_radius + 1) + (_radius + 1); // ball. Color = randomRGB(); ball.r = _radius; _balls.add(ball); }}}} /** * updateBalls() {double maxX = 400; For (Ball Ball in _balls) {ball.x += ball.vx; //x=xo+v*t-----t=1 ball.y += ball.vY; ball.y += ball.aY; / / v = vo + a * t t = 1 -- -- -- -- -- the if (ball. Y > = 160) {/ / than the bottom line, y bounce ball, y = 160; Ball. vY = -ball.vY * 0.99; } if (ball.x > maxX) {// bounce ball. X = maxX; Ball. vX = -ball.vX * 0.99; }} // get a certain amount of something from you?? If (new datetime.now (). tagOfBall = new DateTime.now().millisecondsSinceEpoch; }}Copy the code

Ok, so that’s it for today, a little bit of stuff, and Dart is getting more and more comfortable with the syntax


Postscript: Jie wen standard

1. Growth record and Errata of this paper
Program source code The date of note
V0.1 – making 2018-12-17 Day 2 –Animation + Particle Motion
2. More about me
Pen name QQ WeChat hobby
Zhang Feng Jie te Li 1981462002 zdl1994328 language
My lot My Jane books I’m the nuggets Personal website
3. The statement

1—- This article is originally written by Zhang Fengjie, please note if reproduced

2—- welcome the majority of programming enthusiasts to communicate with each other 3—- personal ability is limited, if there is something wrong welcome to criticize and testify, must be humble to correct 4—- see here, I thank you here for your love and support



// Import 'dart: UI '; const colors = [ Color(0x8833B5E5), Color(0x880099CC), Color(0x889933CC), Color(0x8899CC00), Color(0x88669900), Color(0x88FFBB33), Color(0x88FF8800), Color(0x88FF4444), Color(0x88CC0000) ]; const digit = [ [ [0, 0, 1, 1, 1, 0, 0], [0, 1, 1, 0, 1, 1, 0], [1, 1, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 1, 1], [0, 1, 1, 0, 1, 1, 0] to [0, 0, 1, 1, 1, 0, 0]], / / 0 [[0, 0, 0, 1, 1, 0, 0] to [0, 1, 1, 1, 1, 0, 0] to [0, 0, 0, 1, 1, 0, 0] to [0, 0, 0, 1, 1, 0, 0] to [0, 0, 0, 1, 1, 0, 0], [0, 0, 0, 1, 1, 0, 0] to [0, 0, 0, 1, 1, 0, 0] to [0, 0, 0, 1, 1, 0, 0] to [0, 0, 0, 1, 1, 0, 0], [1, 1, 1, 1, 1, 1, 1]], / / 1 [[0, 1, 1, 1, 1, 1, 0], [1, 1, 0, 0, 0, 1, 1], [0, 0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 1, 1, 0] to [0, 0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0, 0] to [0, 1, 1, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 1, 1], [1, 1, 1, 1, 1, 1, 1]], / / 2 [[1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 1, 1, 0] to [0, 0, 0, 1, 1, 0, 0] to [0, 0, 1, 1, 1, 0, 0], [0, 0, 0, 0, 1, 1, 0] to [0, 0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 1, 1], [0, 1, 1, 1, 1, 1, 0]], / / 3 [[0, 0, 0, 0, 1, 1, 0] to [0, 0, 0, 1, 1, 1, 0] to [0, 0, 1, 1, 1, 1, 0] to [0, 1, 1, 0, 1, 1, 0], [1, 1, 0, 0, 1, 1, 0], [1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 1, 1, 0] to [0, 0, 0, 0, 1, 1, 0] to [0, 0, 0, 0, 1, 1, 0] to [0, 0, 0, 1, 1, 1, 1]], / / 4 [[1, 1, 1, 1, 1, 1, 1], [1, 1, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 0] to [0, 0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 1, 1], [0, 1, 1, 1, 1, 1, 0]], / / 5 [[0, 0, 0, 0, 1, 1, 0] to [0, 0, 1, 1, 0, 0, 0] to [0, 1, 1, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 0], [1, 1, 0, 1, 1, 1, 0], [1, 1, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 1, 1], [0, 1, 1, 1, 1, 1, 0]], / / 6 [[1, 1, 1, 1, 1, 1, 1], [1, 1, 0, 0, 0, 1, 1], [0, 0, 0, 0, 1, 1, 0] to [0, 0, 0, 0, 1, 1, 0] to [0, 0, 0, 1, 1, 0, 0], [0, 0, 0, 1, 1, 0, 0] to [0, 0, 1, 1, 0, 0, 0] to [0, 0, 1, 1, 0, 0, 0] to [0, 0, 1, 1, 0, 0, 0] to [0, 0, 1, 1, 0, 0, 0]], / / 7 [[0, 1, 1, 1, 1, 1, 0], [1, 1, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 1, 1], [0, 1, 1, 1, 1, 1, 0], [1, 1, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 1, 1], [0, 1, 1, 1, 1, 1, 0]], / / 8 [[0, 1, 1, 1, 1, 1, 0], [1, 1, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 1, 1], [0, 1, 1, 1, 0, 1, 1], [0, 0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 1, 1, 0] to [0, 0, 0, 1, 1, 0, 0] to [0, 1, 1, 0, 0, 0, 0]], / / 9 [[0, 0, 0, 0], [0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]] //:];Copy the code