summaryrefslogtreecommitdiff
path: root/FrameRender/P_LineSegment.c
blob: f2236ffd71db5b62f69e7ee16253ca319e2b2141 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include "P_LineSegment.h"
#include "PixelCallback.h"
#include <math.h>
#include <stdlib.h>
#include <string.h>

void rotatePoint(i32* x, i32* y, double angle) {
	i32 xR = *x * cos(angle) + *y * sin(angle);
	i32 yR = - *x * sin(angle) + *y * cos(angle);
	*x = xR;
	*y = yR;
}

void LineSegment_callback(LineSegment* self, struct PixelContext* fc) {
	/* IDK if this is the most efficient, online results seem
	 * to do more complicated calculations.
	 * Center coordianates around aX,aY
	 * Then unrotate bX,bY and x,y relative to 0,0 (aX,aY),
	 * so that bX,bY lies on the horizontal axis.
	 * Now the line is flat from 0,0 to the "right" (increasing x).
	 */
	i32 x = fc->x - self->aX, y = fc->y - self->aY;
	i32 bX = self->bX - self->aX, bY = self->bY - self->aY;

	double phi = atan2(bY, bX);
	rotatePoint(&y, &x, -phi);
	rotatePoint(&bY, &bX, -phi);

	if (0 <= x && x <= bX &&
	    -(i32)self->width / 2 <= y && y <= self->width / 2)
	{
		ARGB_merge(&fc->pixel, self->color);
	}
}

PixelCallback* LineSegment_setup(LineSegment obj) {
	PixelCallback* pca = malloc(sizeof(struct PixelCallback));

	pca->callback = (PixelCallback_callback)LineSegment_callback;
	pca->callback_self = malloc(sizeof(obj));
	memcpy(pca->callback_self, &obj, sizeof(obj));

	return pca;
}