diff options
author | Sid <36409334+heisid@users.noreply.github.com> | 2023-12-21 04:43:41 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-21 04:43:41 +0000 |
commit | c9fdf69ddec787effe76d88e6a606eac054c1bfe (patch) | |
tree | 13ad84c491ac626686aa25eec921b1293504ea32 | |
parent | ccdb9e90612bbaa0bb6357b56c0c95083f6104d6 (diff) | |
parent | 9d0453d24aefbaef33b448a91dceb34e4587fa67 (diff) |
Merge pull request #1 from heisid/vector-field
Vector field
-rw-r--r-- | src/main.c | 213 |
1 files changed, 125 insertions, 88 deletions
@@ -1,78 +1,100 @@ +#include <stdlib.h> +#include <stdio.h> + #include "raylib.h" #include "raymath.h" -typedef struct InitConfig { +typedef struct Config { int SCREEN_WIDTH; int SCREEN_HEIGHT; - char TITLE[20]; + int ORIGIN_X; + int ORIGIN_Y; + char TITLE[50]; int TARGET_FPS; -} InitConfig; +} Config; + +typedef struct Line { + Vector2 start; + Vector2 end; + Color color; +} Line; -typedef struct Ball { - Vector2 pos; +typedef struct Object { + float posX; + float posY; float radius; - float mass; - Vector2 velocity; - Vector2 force; Color color; -} Ball; + float charge; +} Object; -typedef struct Physics { - float gravityConstant; -} Physics; +typedef struct VectorField { + int colSize; + int rowSize; + int spacing; + Line **lines; +} VectorField; -void doInitialization(InitConfig config); -void doDrawing(Ball **balls, int totalBalls); -void doUpdate(Ball **balls, int totalBalls, Physics physics); +void Initialize(Config config); +void InitializeVectorField(VectorField *vectorField, int colSize, int rowSize); +void doDrawing(VectorField *vectorField, int colSize, int rowSize, Object *objects, int objectNum); +void doUpdate(VectorField *vectorField, Object *objects, int objectNum); int main(void) { - InitConfig config = { + Config config = { 1500, 900, - "Just a fucking test", + 1500 / 2, + 900 / 2, + "Force Field Simulator", 60 }; - doInitialization(config); - - Physics physics = { - .gravityConstant = 70.0f, + Initialize(config); + + int spacing = 20; + int colSize = config.SCREEN_WIDTH / spacing - 1; + int rowSize = config.SCREEN_HEIGHT / spacing - 1; + Line **lines = NULL; + VectorField vectorField = { + .colSize = colSize, + .rowSize = rowSize, + .spacing = spacing, + .lines = lines }; + InitializeVectorField(&vectorField, colSize, rowSize); - Ball luna = { - .pos = {(float)config.SCREEN_WIDTH / 2, 0.0f + 100}, - .radius = 5, - .mass = 200, - .velocity = { 50.0f, 0.0f }, - .force = {0.0f, 0.0f}, - WHITE - }; - - Ball potato = { - .pos = {(float)config.SCREEN_WIDTH / 2, (float)config.SCREEN_HEIGHT - 320}, - .radius = 5, - .mass = 200, - .velocity = { -80.0f, 0.0f }, - .force = {0.0f, 0.0f}, - YELLOW + Object object0 = { + .posX = (float)config.ORIGIN_X - 200, + .posY = (float)config.ORIGIN_Y, + .radius = 20, + .color = RED, + .charge = 100 }; - Ball earth = { - .pos = {(float)config.SCREEN_WIDTH / 2, (float)config.SCREEN_HEIGHT / 2 }, + Object object1 = { + .posX = (float)config.ORIGIN_X + 200, + .posY = (float)config.ORIGIN_Y, .radius = 20, - .mass = 15000, - .velocity = { 0.0f, 0.0f }, - .force = {0.0f, 0.0f}, - BLUE + .color = BLUE, + .charge = -100 }; - Ball *balls[] = {&earth, &luna, &potato}; +// Object object2 = { +// .posX = (float)config.ORIGIN_X + 200, +// .posY = (float)config.ORIGIN_Y - 100, +// .radius = 20, +// .color = BLUE, +// .charge = -100 +// }; + + Object objects[] = {object0, object1}; + int objectNum = sizeof(objects) / sizeof(Object); while (!WindowShouldClose()) { - doUpdate(balls, 3, physics); - doDrawing(balls, 3); + doUpdate(&vectorField, objects, objectNum); + doDrawing(&vectorField, colSize, rowSize, objects, objectNum); } CloseWindow(); @@ -80,66 +102,81 @@ int main(void) return 0; } -void doInitialization(InitConfig config) { +void Initialize(Config config) { InitWindow(config.SCREEN_WIDTH, config.SCREEN_HEIGHT, config.TITLE); SetTargetFPS(config.TARGET_FPS); } -//float pix2m(int pixels) { -// // Pixel to meter conversion, 1 pixel = 1 cm -// return 0.01f * (float)pixels; -//} -// -//int m2pix(float metres) { -// return (int)floorf(metres / 0.01f); -//} - -Vector2 computeGravity(Ball *ball1, Ball *ball2, Physics physics) { - // Gravity felt by ball2 - Vector2 displacement = Vector2Subtract(ball1->pos, ball2->pos); - float gravityMag = (physics.gravityConstant * ball1->mass * ball2->mass) / Vector2LengthSqr(displacement); - return Vector2Scale(Vector2Normalize(displacement), gravityMag); +void MemAllocFailed(char *source) { + printf("Memory allocation for %s failed", source); + exit(42); } -Vector2 computeGravityNDimension(Ball *ball1, Ball *ball2, Physics physics, int dimension) { - // Generalisasi. Nyoba kalo ada N-dimensi ruang - Vector2 displacement = Vector2Subtract(ball1->pos, ball2->pos); - float distance = Vector2Length(displacement); - float distanceFactor = (float)pow(distance, dimension - 1); - float gravityMag = (physics.gravityConstant * ball1->mass * ball2->mass) / distanceFactor; - return Vector2Scale(Vector2Normalize(displacement), gravityMag); +//float getRndAngle() { +// float nMax = 360; +// return (float)rand() / ((float)RAND_MAX / nMax); // NOLINT(cert-msc30-c, cert-msc50-cpp) +//} + +void InitializeVectorField(VectorField *vectorField, int colSize, int rowSize) { + vectorField->lines = malloc(rowSize * sizeof(Line*)); + for (int i = 0; i < rowSize; i++) { + vectorField->lines[i] = malloc(colSize * sizeof(Line)); + for (int j = 0; j < colSize; j++) { + Vector2 start = { + (float)((j + 1) * vectorField->spacing), + (float)((i + 1) * vectorField->spacing) + }; + Vector2 end = {start.x + 5, start.y - 5}; + Line line = { + .start = start, + .end = end, + .color = WHITE + }; + vectorField->lines[i][j] = line; + } + } } -void doUpdate(Ball **balls, int totalBalls, Physics physics) { +void doUpdate(VectorField *vectorField, Object *objects, int objectNum) { + float forceConstant = 5000.0f; float dt = GetFrameTime(); - for (int i = 0; i < totalBalls; i++) { - Ball *ball = balls[i]; - // Sum over gravity felt from all other balls - Vector2 gravityTotal = {0.0f, 0.0f}; - for (int j = 0; j < totalBalls; j++) { - if (i != j) { - Ball *otherBall = balls[j]; - Vector2 gravity = computeGravity(otherBall, ball, physics); - gravityTotal = Vector2Add(gravityTotal, gravity); + for (int i = 0; i < vectorField->rowSize; i++) { + for (int j = 0; j < vectorField->colSize; j++) { + Vector2 resultant = Vector2Zero(); + for (int k = 0; k < objectNum; k++) { + Object object = objects[k]; + Vector2 distanceVector = Vector2Subtract(vectorField->lines[i][j].start, (Vector2){object.posX, object.posY}); + float fieldStrength = forceConstant * object.charge / Vector2LengthSqr(distanceVector); + Vector2 force = Vector2Normalize(distanceVector); + force = Vector2Scale(force, fieldStrength); + resultant = Vector2Add(force, resultant); + } + float resultantMag = Clamp(Vector2Length(resultant), -20.0f, 20.0f); + if (fabsf(resultantMag) < 2.0f) { + resultantMag = resultantMag >= 0 ? 2.0f : -2.0f; } + resultant = Vector2Normalize(resultant); + resultant = Vector2Scale(resultant, resultantMag); + vectorField->lines[i][j].end = Vector2Add(vectorField->lines[i][j].start, resultant); } - // Update position from last velocity - ball->pos = Vector2Add(ball->pos, Vector2Scale(ball->velocity, dt)); - // a = F / m - Vector2 acceleration = Vector2Scale(gravityTotal, 1.0f / ball->mass); - // Update velocity for next frame - ball->velocity = Vector2Add(ball->velocity, Vector2Scale(acceleration, dt)); } +// objects[0].posX += 10 * dt; +// objects[1].posX -= 10 * dt; } -void doDrawing(Ball **balls, int totalBalls) { +void doDrawing(VectorField *vectorField, int colSize, int rowSize, Object *objects, int objectNum) { BeginDrawing(); ClearBackground(BLACK); - for (int i = 0; i < totalBalls; i++) { - Ball *ball = balls[i]; - DrawCircleV(ball->pos, ball->radius, ball->color); + for (int i = 0; i < rowSize; i++) { + for (int j = 0; j < colSize; j++) { + DrawLineV(vectorField->lines[i][j].start, vectorField->lines[i][j].end, vectorField->lines[i][j].color); + } + } + for (int i = 0; i < objectNum; i++) { + Object object = objects[i]; + DrawCircle((int)object.posX, (int)object.posY, object.radius, object.color); } EndDrawing(); |