summaryrefslogtreecommitdiff
path: root/FrameRender/P_LineSegment.c
diff options
context:
space:
mode:
Diffstat (limited to 'FrameRender/P_LineSegment.c')
-rw-r--r--FrameRender/P_LineSegment.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/FrameRender/P_LineSegment.c b/FrameRender/P_LineSegment.c
new file mode 100644
index 0000000..f2236ff
--- /dev/null
+++ b/FrameRender/P_LineSegment.c
@@ -0,0 +1,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;
+}