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);
i32 halfWidth = self->width / 2;
if (0 <= x && x <= bX && -halfWidth <= y && y <= halfWidth)
{
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;
}
|