Education

Software Development Executive - II

Oct 24, 2023

Aug 29, 2023

In today's digital world, a vast majority of tools and processes rest on a strong foundation of math. Fundamental mathematical concepts like vectors and matrices are paramount in crafting sophisticated software, as they grant developers absolute control over space and time manipulations. For Dart and Flutter developers, the **Vector Math library** emerges as a powerful ally. Let's embark on a course through the world of Flutter vector math and understand how it serves as a vital pillar in the development of complex apps.

The vector math library brings robust functionality for 2D, 3D, and even 4D applications. This powerful library builds upon the Dart programming language's core strengths and Flutter's versatile platform support. Whether you're creating animations, working on collision detection, or handling advanced rendering tasks, this Library might be one you don't want to leave out of your project's toolset.

Want to use the latest version of the Flutter Vector Math library in your project and understand how it can maximize your productivity and efficiency? You're in the right place. Throughout this blog, I will guide you through its diverse holding of vector and matrix types, quaternion, utilities, and fully documented functionality. I will use real-world examples to make sense of the Vector Math library's usage, write code, and produce tangible results. Let's dive in!

Understanding the vector math library is the first step in this exciting course. The Vector Math package offers a comprehensive and fully documented suite of classes and functions for handling vectors and matrices in Dart. Whether you're working on complex 3D animations, designing immersive 2D games, or even wrangling with the fourth dimension in futuristic apps, this package got you covered.

In Vector Math, **vector** and **matrix** are core components that hold pivotal values for modern-day computations. Vectors encapsulate direction and magnitude, crucial for tackling graphics, physics, and more. Matrices, on the other hand, are instrumental in transformations that change the position or orientation of objects.

The Vector Math package isn't all about vectors and matrices, of course. It offers other classes such as Quaternion for handling rotations. The cross-product of vectors, various constants serving as computational tools, and a user-friendly approach to getters and setters simplify your usage of this library. The Vector Math package is highly optimized for maximum performance and efficiently tested to reduce debug hours.

The Vector Math package equips you with tools for detecting collisions between AABB, rays, spheres, and more. Plus, the color and rendering-related operations can make your apps shine brighter!

Notably, the vector math library continues to gather recognition and support from Flutter and Dart communities. Big guns like Flutter and Flame already employ the vector math package in their codebases.

Whether you're handling straightforward 2D transformations or delving deep into the multiverse with 4D vectors, the robust Vector Math library in Flutter can help you solve complex math with ease and efficiency.

To use the Vector Math package, you first need the Dart/Flutter SDK. Dart is the programming language behind the development of Flutter apps. It's easy to download and set up Dart on many platform systems. Follow the steps in the Dart documentation to get it running smoothly.

Once you have the Dart SDK set up, you can run the Vector Math package in your project.

`1 // Using Dart: 2 $ dart pub add vector_math 3 4 // Using Flutter: 5 $ flutter pub add vector_math 6`

These commands add a line to your package's pubspec.yaml and run an implicit dart pub get. If your editor supports **dart pub get** or **flutter pub get**, you can utilize these commands. For further details, check the documentation provided by Dart.

Just installing the package isn't enough. You need to import it into your Dart code. Importing allows your app to utilize all functions, constants, and classes stored within the library.

`1 import 'package:vector_math/vector_math.dart'; 2`

Incorporating the Vector Math package in your Flutter apps involves understanding the various classes and functions it provides. Here, we will discuss some of the critical components, including vector types, quaternion for animations, collision detection, and others.

In the domain of Vector Math, dimensions play a crucial role. The library provides 2D, 3D, and 4D vector types for various applications. Whether you’re developing a 2D game or a 3D animation, understanding vector manipulation is essential. In 4D vectors, the fourth component can be anything like time or an extra spatial dimension, depending on your needs.

Let's look at an example of how to manipulate vectors:

`1 import 'package:vector_math/vector_math.dart'; 2 3 void main() { 4 Vector3 x = new Vector3.zero(); // Zero vector 5 Vector4 y = new Vector4.all(4.0); // Vector with all values as 4.0 6 x.zyx = y.xzz; // Sets z,y,x of vector x to the values in x,z,z of vector y 7 } 8`

Quaternions are useful for animating rotations in a 3D space. They provide an efficient, compact, and error-free way of encoding these rotations.

Below is an example of rotating a vector using a quaternion:

`1 import 'dart:math'; 2 import 'package:vector_math/vector_math.dart'; 3 4 void main() { 5 Vector3 axis = new Vector3(1.0, 0.0, 0.0); //The X-axis 6 double angle = PI / 2.0; //90 degrees 7 Quaternion q = new Quaternion.axisAngle(axis, angle); //Quaternion 8 Vector3 point = new Vector3(1.0, 1.0, 1.0); //A point 9 q.rotate(point); //Rotate the point 10 } 11`

Vector math provides a flexible syntax for accessing and manipulating vectors in Dart. This syntax is akin to GLSL (Graphics Library Shader Language), a high-level language used for programming shader effects.

Traditionally, accessing and setting values within vector types happens using simple indexes. But Flutter's vector math library provides a more intuitive way to interact with and modify these values. You can use GLSL-style swizzling operators to read or write to components in any order you like.

Here's an example using GLSL getter and setter syntax. In this block of code, we create two vectors and then make use of the GLSL syntax to set values in our vector.

`1 import 'package:vector_math/vector_math.dart'; 2 3 void main() { 4 Vector3 x = new Vector3.zero(); // Zero vector 5 Vector4 y = new Vector4.all(4.0); // Vector with all values as 4.0 6 x.zyx = y.xzz; // Sets z,y,x of vector x to the values in x,z,z of vector y 7 } 8`

In this example, "zyx" and "xzz" are known as swizzle operators. The ".zyx" on the left-hand side of the assignment corresponds to the ".xzz" on the right-hand side. This interchangeability and the ability to cater to any order brings power and flexibility to the syntax.

Understanding and using such syntax can make your code cleaner and more organized, enhancing your coding efficiency.

Vector transformations are an integral part of 3D programming. With Vector Math, such transitions become a breeze. You can perform a multitude of transformations, including translation, rotation, and scaling.

Matrix transformations are handy tools in the vector math package. Matrices can accomplish rotations, scaling, and translations in simple steps. Hence, mastering matrix transformations is key to manipulating objects in 3D space efficiently.

Here's an example. In this block, we first define a transformation matrix that rotates about the Y-axis, followed by translation. We then use this transformation to change the position of a point.

`1 import 'dart:math'; 2 import 'package:vector_math/vector_math.dart'; 3 4 void main() { 5 Matrix4 T = new Matrix4.rotationY(PI * 0.5)..translate(5.0, 2.0, 3.0); 6 // Rotation of PI/2 radians around the Y axis followed by a translation to (5.0, 2.0, 3.0). 7 8 Vector3 position = new Vector3(1.0, 1.0, 1.0); 9 // Position - original state 10 11 T.transform3(position); 12 // Position - after transformation 13 } 14`

In this example, first, we initiated a Matrix4 object with a rotation of PI/2 radians around the Y-axis, and then we translated it to the point (5.0, 2.0, 3.0). After this, we created a Vector3 object for position which has its initial values as (1, 1, 1). We then transformed this position using the function *transform3*, which transforms the 3-dimensional vector and stores the result in the original vector.

Matrix inversion is another powerful tool that comes with the Vector Math package. In mathematics, the inverse of a matrix is instrumental in solving systems of equations. This concept extends to 3D programming, where you may often need to reverse a transformation, which is achieved by inverting the transformation matrix.

In Vector Math, both Matrix3 and Matrix4 classes have a method named invert(), which makes the matrix its own inverse. Matrix inversion in 3D programming is common when you need to transform from the world space to the local space of an object.

Here's an example of how to make a matrix its own inverse:

`1 import 'dart:math'; 2 import 'package:vector_math/vector_math.dart'; 3 4 void main() { 5 Matrix4 T = new Matrix4.rotationY(PI * 0.5)..translate(5.0, 2.0, 3.0); 6 // A Matrix transformation 7 8 T.invert(); 9 // Inverts T 10 } 11`

In the code above, first, we initiated a Matrix T with a transformation. Next, we inverted T, which means we created a new transformation that is the reverse of the initial transformation.

This powerful method is essential in the vast playground of 3D programming and extends beyond just space transformations.

Quaternion is a handy tool in 3D programming, especially used for encoding rotations. It overcomes the problem of gimbal lock and provides a computationally efficient means to interpolate rotations, which is crucial in animation.

In Vector Math, the Quaternion class allows you to create a quaternion from an axis and an angle of rotation, which in turn enables the rotation of any point or vector in 3-dimensional space.

Here’s an example of rotating a vector using a quaternion:

`1 import 'dart:math'; 2 import 'package:vector_math/vector_math.dart'; 3 4 void main() { 5 // The X axis. 6 Vector3 axis = new Vector3(1.0, 0.0, 0.0); 7 // 90 degrees. 8 double angle = PI / 2.0; 9 // Quaternion encoding a 90 degree rotation along the X axis. 10 Quaternion q = new Quaternion.axisAngle(axis, angle); 11 12 Vector3 point = new Vector3(1.0, 1.0, 1.0); 13 // A point. 14 q.rotate(point); 15 // Rotate point by q. 16 } 17`

In this block of code, we first define an axis as the X-axis and define the angle of rotation as 90 degrees (PI radians). We then create a quaternion to represent this rotation. Finally, we use this quaternion to rotate a point around the X-axis by 90 degrees.

Collision detection is a commonly used technique in 3D graphics and game development. Understanding objects' spatial relationships and making meaningful interactions has several applications, from physics simulations to enhancing user experiences in video games.

One simple but effective method for collision detection involves Axis-Aligned Bounding Boxes (AABB). They provide an easy way to calculate whether two objects collide, and due to axis alignment, calculations become more manageable.

Here's a simple example showing how to check if two Axis-Aligned Bounding Boxes intersect:

`1 import 'package:vector_math/vector_math.dart'; 2 3 void main() { 4 Aabb2 aabbOne = new Aabb2.minMax(new Vector2.zero(), new Vector2(4.0, 4.0)); 5 // Define the first box 6 Aabb2 aabbTwo = new Aabb2.minMax(new Vector2(5.0, 5.0), new Vector2(6.0, 6.0)); 7 // Define the second box 8 aabbTwo.hullPoint(new Vector2(3.0, 3.0)); 9 // Extend the second box to another point 10 bool intersect = aabbOne.intersectsWithAabb2(aabbTwo); 11 // Does the first box intersect with the Second box? 12 } 13`

In this code block, there are AABBs defined by the minimum and maximum points (lower left and upper right corner of the box). After we defined the two boxes, we extended one of them to cover another point, forced to show an intersection. The ** intersectsWithAabb2** function then checked whether an intersection occurs between the first and second box.

Yet another critical aspect of graphics programming and game development is the intersection of a ray with a sphere. In vector math, your ray is an object with an origin and direction. Together with spheres, they offer a simple yet powerful geometric representation of many real-world objects.

Within Vector math, the Ray class represents a ray with a start and direction vector. On the other hand, the Sphere class represents a sphere defined by a center and radius. Both classes provide pertinent methods to calculate intersections.

Here’s an example showing how to check where a ray and a sphere intersect:

`1 import 'package:vector_math/vector_math.dart'; 2 3 void main() { 4 Ray ray = new Ray.originDirection(new Vector3.zero(), new Vector3(1.0, 0.0, 0.0)); 5 // Define a ray starting at the origin and going in positive x-direction 6 Sphere sphere = new Sphere.centerRadius(new Vector3(5.0, 0.0, 0.0), 2.0); 7 // Define a sphere with center at (5.0 0.0 0.0) and radius of 2 8 double distanceFromOrigin = ray.intersectsWithSphere(sphere); 9 // Check the intersection of the ray with the sphere and get the distance from the origin 10 Vector3 position = ray.at(distanceFromOrigin); 11 // Determine the position of intersection 12 } 13`

In this block of code, we created a Ray pointed in the positive x-direction. We also created a Sphere centered at (5.0, 0.0, 0.0). The *intersectsWithSphere* method finds if the ray intersects the sphere, and if so, the distance from the ray's origin is obtained. The *at* method then returns the position of intersection.

Colors also play a significant role when it comes to 3D programming or game design, and Vector Math offers a suite of tools and functions to manipulate colors.

Vector Math offers built-in colors stored in 4-dimensional vectors and manipulations like RGB to HSL conversion, parsing color from Hex strings, or converting color to grayscale.

Here’s an example showcasing some of these operations:

`1 import 'package:vector_math/vector_math.dart'; 2 3 void main() { 4 Vector4 red = Colors.red; 5 // Access a built-in color 6 Vector4 gray = new Vector4.zero(); 7 // A vector for grayscale color 8 Colors.toGrayscale(red, gray); 9 // Convert the red color to grayscale 10 Vector4 blue = new Vector4.zero(); 11 // A vector for blue color 12 Colors.fromHexString('#0000FF', blue); 13 // Parse the blue color from a hex string 14 Colors.rgbToHsl(blue, blue); 15 // Convert the blue RGB color to HSL 16 blue.z *= 0.5; 17 // Reduce the lightness of the color by 50% 18 Colors.hslToRgb(blue, blue); 19 // Convert the modified HSL color back to RGB 20 } 21`

In this block of code, we accessed a built-in red color provided by the Colors class which is a 4-dimensional vector where RGBA components are stored in the x, y, z, and w components, respectively.

Further operations include converting it to grayscale, parsing colors from hex strings, manipulating color lightness, and converting colors between RGB and HSL representations.

This suite of Vector Math functions for colors provides a versatile toolkit for bringing life to your applications and games with vibrant colors and gradients.

Ensuring the accuracy and reliability of your Dart and Flutter applications is paramount. This "health check" often comes in the form of unit tests. In the Vector Math package, there are also facilities available to run unit tests for peace of mind with code quality and performance.

Unit testing is a software testing method by which individual units of source code are tested to determine whether they are ready to use. In the context of the Vector Math package, you might want to run unit tests to ensure that your vectors, matrices, and other mathematical objects are performing as expected.

To run the included unit tests in Vector Math, you generally would do this:

`1 ~/src/vector_math/> dart test 2`

After running these unit tests, you'll have a better understanding of whether your code is functioning correctly, allowing you to move forward with confidence.

Remember, just like keeping up with the latest version of Vector Math for its enhanced features and fixes, it's essential to continuously test your code for maximum performance and security.

Vector Math 64 is a variant of Vector Math that uses 64-bit floating point numbers instead of 32-bit. This increases the precision of your calculations, which is very useful in applications such as 3D Game Development, Computer Graphics, Machine Learning, etc. Let's take a look at how you can generate Vector Math 64 in your Dart application.

To generate Vector Math 64 in Dart, you can use the built-in Dart tool. Here's how you can generate it:

`1 ~/src/vector_math/> dart tool/generate_vector_math_64.dart 2`

As developers, always keep in mind the balance between performance and precision. If your application doesn't demand high-precision calculations, using Vector Math is sufficient and could lead to better performance. However, for applications requiring high precision, Vector Math 64 is your go-to toolbox.

Many developers often confuse Dart Vector Math with Flutter Vector Math. While they share many similarities, it's crucial to differentiate them based on use-case.

Dart Vector Math is primarily suited for server-side Dart applications or command-line scripts where you typically perform heavy scientific computations.

On the other hand, Flutter Vector Math, while sharing many features with Dart Vector Math, is tailored more towards Flutter applications. It becomes crucial when dealing with animations, graphics, and user interactions.

Whether it be for game development, simulation creation, or general Flutter app development, the Vector Math library is a potent tool. From handling complex dimensional vectors, encoding rotations, and collision detection, to even managing colors, and string manipulations, Vector Math offers a comprehensive and fully-documented suite of functionality that can make your coding journey smoother.

By incorporating Vector Math in your projects, you can effectively enhance their performance, make your code cleaner, and speed up your coding process, thus leaving a significant imprint in your developmental work.

I hope this dive into Vector Math has armed you with yet another potent tool for your Flutter development endeavours. Embrace the math, and elevate your apps! 🚀