Skip to content

Instantly share code, notes, and snippets.

@Leowbattle
Created June 26, 2023 15:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Leowbattle/0817c03a7a75d4a820a3b28b76f43710 to your computer and use it in GitHub Desktop.
Save Leowbattle/0817c03a7a75d4a820a3b28b76f43710 to your computer and use it in GitHub Desktop.
#include <math.h>
#include <stdlib.h>
#include <raylib.h>
#include <raymath.h>
typedef struct Hermite {
float x;
float y;
float d;
} Hermite;
// 1 dimensional cubic hermite spline interpolation
float hermite(float x, Hermite* p, int n) {
if (x < p[0].x || x > p[n - 1].x) {
return NAN;
}
int i;
for (i = 0; i < n - 1; i++) {
if (x >= p[i].x && x <= p[i + 1].x) {
break;
}
}
float x0 = p[i].x;
float y0 = p[i].y;
float d0 = p[i].d;
float x1 = p[i + 1].x;
float y1 = p[i + 1].y;
float d1 = p[i + 1].d;
float X = (x - x0) / (x1 - x0);
float a = d0 + d1 + 2 * y0 - 2 * y1;
float b = 3 * y1 - 3 * y0 - 2 * d0 - d1;
float c = d0;
float d = y0;
return d + X * (c + X * (b + X * a));
}
Hermite C[3] = {
{0, 1, 0},
{1, 0.28f, 0},
{4, 1.73, 0},
};
typedef struct Point {
Vector3 pos;
Color c;
} Point;
int cmp_point(const void* a, const void* b) {
Point* pa = a;
Point* pb = b;
return pa->pos.z < pb->pos.z ? 1 : -1;
}
int main() {
int w = 640;
InitWindow(w, w, "Cup");
SetTargetFPS(60);
const int n = 40;
const int n2 = 40;
Point points[n * n2];
while (!WindowShouldClose()) {
BeginDrawing();
ClearBackground(BLACK);
for (int i = 0; i < n; i++) {
float x = Remap(i, 0, n - 1, 0, 4);
float y = hermite(x, C, 3);
for (int j = 0; j < n2; j++) {
float t = Remap(j, 0, n2 - 1, 0, 2 * PI);
float phase = Remap(i, 0, n - 1, 0, PI) + GetTime();
float X = cosf(t + phase) * y * 50 + w / 2;
float Y = (4 - x) * 50 + w / 2;
float Z = sinf(t + phase) * y * 50 + w / 2;
float camY = 80;
float camT = 30 * DEG2RAD;
Y = Y * cosf(camT) - Z * sinf(camT);
Z = Y * sinf(camT) + Z * cosf(camT);
Y += camY;
Color c = {(j % 2 + 1) * 127, (i % 2) * 127, 0, 255};
points[i * n + j] = (Point){(Vector3){X, Y, Z}, c};
}
}
qsort(points, n * n2, sizeof(Point), cmp_point);
for (int i = 0; i < n * n2; i++) {
Point p = points[i];
DrawCircleV((Vector2){p.pos.x, p.pos.y}, 5, p.c);
}
EndDrawing();
}
CloseWindow();
return 0;
}
// https://twitter.com/2DArray/status/1670644975338418176
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment