summaryrefslogtreecommitdiff
path: root/renders/anim_sort.c
diff options
context:
space:
mode:
authorSyndamia <kamen@syndamia.com>2026-03-31 21:07:19 +0300
committerSyndamia <kamen@syndamia.com>2026-03-31 21:07:19 +0300
commit69743511c4bc59ad9ff84fa223f7a7c2625522f2 (patch)
treec69f278b32c526c7918df62fc70c0152486af166 /renders/anim_sort.c
parent9b4a190499144090cf6eac49bf5a5ccdcf07099d (diff)
downloadppm_graphics-69743511c4bc59ad9ff84fa223f7a7c2625522f2.tar
ppm_graphics-69743511c4bc59ad9ff84fa223f7a7c2625522f2.tar.gz
ppm_graphics-69743511c4bc59ad9ff84fa223f7a7c2625522f2.zip
feat(renders): Implement sorting animationHEADmaster
Diffstat (limited to 'renders/anim_sort.c')
-rw-r--r--renders/anim_sort.c202
1 files changed, 202 insertions, 0 deletions
diff --git a/renders/anim_sort.c b/renders/anim_sort.c
new file mode 100644
index 0000000..f8e1a71
--- /dev/null
+++ b/renders/anim_sort.c
@@ -0,0 +1,202 @@
+#include "../AnimationRender/AnimationRender.h"
+#include "../AnimationRender/F_Draw.h"
+#include "../AnimationRender/F_FrameRange.h"
+#include "../AnimationRender/F_Interpolate.h"
+#include "../AnimationRender/FrameCallback.h"
+#include "../FrameRender/P_Circle.h"
+#include "../FrameRender/P_Square.h"
+#include "../FrameRender/P_TransformCenter.h"
+#include "../FrameRender/PixelCallback.h"
+#include <stdlib.h>
+
+struct FrameCallbackArray {
+ FrameCallback** arr;
+ u32 count;
+ u32 allocated;
+
+ const u32* elements;
+ const TransformCenter* positions;
+ const PixelCallback** callbacksPositions;
+};
+
+void
+FrameCallbackArray_push(struct FrameCallbackArray* fca, u32 from, u32 to, u32 start, u32 end) {
+ // resize
+ if (fca->count + 5 >= fca->allocated) {
+ fca->allocated = fca->allocated == 0 ? 8 : fca->allocated << 1;
+ FrameCallback** arrLarger = calloc(sizeof(FrameCallback*), fca->allocated);
+
+ for (unsigned i = 0; i < fca->count; ++i)
+ arrLarger[i] = fca->arr[i];
+ free(fca->arr);
+ fca->arr = arrLarger;
+ }
+
+ fca->arr[fca->count++] = NULL;
+ fca->arr[fca->count++] = FrameRange_setup((FrameRange){
+ .startFrame = start, .endFrame = end,
+ });
+ fca->arr[fca->count++] = Interpolate_setup((Interpolate){
+ .startValue = fca->positions + from, .endValue = fca->positions + to,
+ .value = fca->callbacksPositions[fca->elements[from]]->callback_self,
+ .interpolate = (f_interpolate)Interpolate_TransformCenter,
+ });
+}
+
+struct SwapCallbackArgs {
+ struct FrameCallbackArray* fca;
+ u32* frames;
+ u32 duration;
+ u32 rest;
+};
+
+void
+swap_callback(struct SwapCallbackArgs* sca, u32 from, u32 to) {
+ FrameCallbackArray_push(sca->fca,
+ from, to, *sca->frames, *sca->frames + sca->duration);
+ FrameCallbackArray_push(sca->fca,
+ to, from, *sca->frames, *sca->frames + sca->duration);
+ *sca->frames += sca->duration + sca->rest;
+}
+
+void
+swap_u32(struct SwapCallbackArgs* sca, u32* a, u32 i, u32 j) {
+ swap_callback(sca, i, j);
+ u32 temp = a[i];
+ a[i] = a[j];
+ a[j] = temp;
+}
+
+void
+bubble_sort(u32* a, u32 length, struct SwapCallbackArgs* sca) {
+ for (u32 i = 0; i < length - 1; ++i) {
+ for (u32 j = 0; j < length - 1 - i; ++j) {
+ // Sorts in ascending order
+ if (a[j] > a[j+1])
+ swap_u32(sca, a, j, j+1);
+ }
+ }
+}
+
+void
+insertion_sort(u32* a, u32 length, struct SwapCallbackArgs* sca) {
+ for (u32 i = 1; i < length; ++i) {
+ u32 j = i;
+ // Sorts in descending order
+ while (j > 0 && a[j-1] < a[j]) {
+ swap_u32(sca, a, j, j-1);
+ --j;
+ }
+ }
+}
+
+void
+selection_sort(u32* a, u32 length, struct SwapCallbackArgs* sca) {
+ for (u32 i = 0; i < length - 1; ++i) {
+ int minind = i;
+ for (int j = i + 1; j < length; ++j) {
+ // Sorts in ascending order
+ if (a[j] < a[minind])
+ minind = j;
+ }
+
+ if (minind != i)
+ swap_u32(sca, a, i, minind);
+ }
+}
+
+int
+main() {
+ /* Sesttings */
+
+ // Animation settings
+ u32 width = 960;
+ u32 height = 320;
+ const u32 FPS = 60;
+
+ // Elements settings
+ u32 elements[] = { 5, 4, 3, 2, 1, 0 };
+ #define ELEMENTS_COUNT (sizeof(elements) / sizeof(*elements))
+ u32 elementSpacing = 40;
+
+ /* Implementation */
+
+ // Spaced out elements
+ u32 minRadius = (width / ELEMENTS_COUNT) / 4 - elementSpacing / 2;
+ u32 maxRadius = (width / ELEMENTS_COUNT) / 2 - elementSpacing / 2;
+
+ TransformCenter positions[ELEMENTS_COUNT];
+ for (unsigned i = 0; i < ELEMENTS_COUNT; ++i) {
+ positions[i].centerX = i * width / ELEMENTS_COUNT + maxRadius + elementSpacing / 2;
+ positions[i].centerY = height / 2;
+ }
+
+ PixelCallback* callbacksPositions[ELEMENTS_COUNT];
+ PixelCallback* callbacksElements[1 + ELEMENTS_COUNT * 3] = {
+ /* Background */
+ Square_setup((Square){
+ .size = width, .color = 0xFFF0F0F0,
+ }),
+ };
+ for (unsigned i = 0; i < ELEMENTS_COUNT; ++i) {
+ double p = elements[i] / (ELEMENTS_COUNT - 1.0);
+
+ callbacksElements[1+i*3] = NULL;
+ callbacksElements[1+i*3+1] = callbacksPositions[elements[i]] = TransformCenter_setup(positions[i]);
+ callbacksElements[1+i*3+2] = Circle_setup((Circle){
+ .radius = minRadius * (1-p) + maxRadius * p,
+ .color = 0xFF000000 + 0xFFFF * p,
+ });
+ }
+ u32 callbacksElementsSize = 1 + ELEMENTS_COUNT * 3;
+
+ // Elements movement
+ u32 frames = FPS;
+
+ struct FrameCallbackArray fca = {
+ .arr = NULL,
+ .elements = elements,
+ .positions = positions,
+ .callbacksPositions = (const PixelCallback**)callbacksPositions,
+ };
+ struct SwapCallbackArgs sca = {
+ .fca = &fca,
+ .frames = &frames,
+ .duration = FPS * 1,
+ .rest = FPS * 0.5,
+ };
+
+ // Sort
+
+ bubble_sort(elements, ELEMENTS_COUNT, &sca);
+ insertion_sort(elements, ELEMENTS_COUNT, &sca);
+ selection_sort(elements, ELEMENTS_COUNT, &sca);
+
+ frames += FPS;
+
+ // Render
+
+ fca.arr[fca.count++] = NULL;
+ fca.arr[fca.count++] = Draw_setup((Draw){
+ .callbacks = (const PixelCallback**)callbacksElements, .sizeCallbacks = callbacksElementsSize,
+ });
+
+ FrameCallback** callbacksMove = fca.arr;
+ u32 callbacksMoveSize = fca.count;
+ RenderAnimation(width, height, frames, (const FrameCallback**)callbacksMove, callbacksMoveSize);
+
+ // Free
+ for (u32 i = 0; i < callbacksElementsSize; ++i) {
+ if (callbacksElements[i] == NULL) continue;
+ free(callbacksElements[i]->callback_self);
+ free(callbacksElements[i]);
+ }
+ for (u32 i = 0; i < callbacksMoveSize; ++i) {
+ if (callbacksMove[i] == NULL) continue;
+ free(callbacksMove[i]->callback_self);
+ free(callbacksMove[i]);
+ }
+ free(callbacksMove);
+
+ return 0;
+}