# A month with C and the terminal - Part 2

>> Part 2, Line drawing + simple linear algebra.

Posted on | 547 words | ~3 minute read

This is a 3 part series!

# Line drawing + simple linear algebra

After the simple physics plotter, I wanted to try using 2x2 matricies for transformations like rotation, scale and shear. It led me to this video.

Youtube - Linear transformations and matrices | Chapter 3, Essence of linear algebra - 3Blue1Brown

After watching, I came up with these initial functions

``````// Vadd();
// VSmultiply();
//   Multiply vector by a number

typedef struct{
double ix; double jx;
double iy; double jy;
}MATRIX;

VECTOR Mmul(VECTOR vec, MATRIX mat){
VECTOR Ihat = {mat.ix,mat.iy};
VECTOR Jhat = {mat.jx,mat.jy};

VSmultiply(Ihat,vec.x),
VSmultiply(Jhat,vec.y)
);

}
``````

It takes a 2D vector as input, then transforms it by the 2x2 input matrix. Construct a matrix then apply it to the positions of the objects vertices.

# Rotation matrix

``````MATRIX Mrotate(double degrees){
return (MATRIX)
{
cos(r), -sin(r),
sin(r),  cos(r)
};
}
``````

# Scale matrix

``````MATRIX Mscale(double s){
return (MATRIX)
{
0, s,
s, 0
};
}
``````

Objects contain their own transformation matrix that is applied anytime it is rendered to the buffer. Using matrix to matrix multiplication, you can combine two matricies together into one master matrix that you can set an objects transform to with this function …

``````// Mmultiply();
//   Multiply (or "combine") matricies
// Mscale();
//   Return scale matrix by factor
// Mrotate();
//   Return rotation matrix by degrees

&scene,         // scene struct
(VECTOR){0,0},  // position
5,15,           // dimensions
PURPLE,         // colour
true     // rendered as wireframe?
);

// ... int main() ...

// apply scale and rotation matrix
applyTransformObject(
Mmultiply(
Mscale(sin(anim.elapsed)),
Mrotate(anim.elapsed*100)
)
);
``````

Now matricies are out of the way, its time to talk about drawing lines. I drew lines with Bresenham’s line algorithm.

Bresenham’s line algorithm - Wikipedia

The pseudocode on Wikipedia is as follows

``````plotLine(x0, y0, x1, y1)
dx = abs(x1 - x0)
sx = x0 < x1 ? 1 : -1
dy = -abs(y1 - y0)
sy = y0 < y1 ? 1 : -1
error = dx + dy

while true
plot(x0, y0)
if x0 == x1 && y0 == y1 break
e2 = 2 * error
if e2 >= dy
if x0 == x1 break
error = error + dy
x0 = x0 + sx
end if
if e2 <= dx
if y0 == y1 break
error = error + dx
y0 = y0 + sy
end if
end while
``````

To draw “wireframe” rectangles, 4 line draw calls must be used to outline the bounds of the shape. The bounds can also be transformed by the objects own matrix.

For animation, a new standardised definition was needed. This is the outline of how to create an animation struct and manipulate it

``````typedef struct{
unsigned int fps;
double delta;
double elapsed;
}Animation;

Animation anim = createAnimation(60);
// takes fps as input, then constructs
// and returns the struct

while(1){
printf("%g", anim.elapsed);
printf("%g", anim.delta);
printf("%u", anim.fps);

animationFrame(&anim);
// wait for single frame
// then manipulate anim.elapsed
}
``````

This system is used extensively in this and in further projects because creating animated frames is much simpler.

This project was the product of wanting to learn basic linear algebra and simple transformations in preparation for the project I did after, the ASCII 3D engine.

Next part!