summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.idea/misc.xml3
-rw-r--r--src/main.c213
2 files changed, 91 insertions, 125 deletions
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 79b3c94..0b76fe5 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
+ <component name="CMakePythonSetting">
+ <option name="pythonIntegrationState" value="YES" />
+ </component>
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
</project> \ No newline at end of file
diff --git a/src/main.c b/src/main.c
index e536730..519dbfc 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,100 +1,78 @@
-#include <stdlib.h>
-#include <stdio.h>
-
#include "raylib.h"
#include "raymath.h"
-typedef struct Config {
+typedef struct InitConfig {
int SCREEN_WIDTH;
int SCREEN_HEIGHT;
- int ORIGIN_X;
- int ORIGIN_Y;
- char TITLE[50];
+ char TITLE[20];
int TARGET_FPS;
-} Config;
-
-typedef struct Line {
- Vector2 start;
- Vector2 end;
- Color color;
-} Line;
+} InitConfig;
-typedef struct Object {
- float posX;
- float posY;
+typedef struct Ball {
+ Vector2 pos;
float radius;
+ float mass;
+ Vector2 velocity;
+ Vector2 force;
Color color;
- float charge;
-} Object;
+} Ball;
-typedef struct VectorField {
- int colSize;
- int rowSize;
- int spacing;
- Line **lines;
-} VectorField;
+typedef struct Physics {
+ float gravityConstant;
+} 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);
+void doInitialization(InitConfig config);
+void doDrawing(Ball **balls, int totalBalls);
+void doUpdate(Ball **balls, int totalBalls, Physics physics);
int main(void)
{
- Config config = {
+ InitConfig config = {
1500,
900,
- 1500 / 2,
- 900 / 2,
- "Force Field Simulator",
+ "Just a fucking test",
60
};
- 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
+ doInitialization(config);
+
+ Physics physics = {
+ .gravityConstant = 70.0f,
};
- InitializeVectorField(&vectorField, colSize, rowSize);
- Object object0 = {
- .posX = (float)config.ORIGIN_X - 200,
- .posY = (float)config.ORIGIN_Y,
- .radius = 20,
- .color = RED,
- .charge = 100
+ 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
};
- Object object1 = {
- .posX = (float)config.ORIGIN_X + 200,
- .posY = (float)config.ORIGIN_Y,
- .radius = 20,
- .color = BLUE,
- .charge = -100
+ 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 object2 = {
-// .posX = (float)config.ORIGIN_X + 200,
-// .posY = (float)config.ORIGIN_Y - 100,
-// .radius = 20,
-// .color = BLUE,
-// .charge = -100
-// };
+ Ball earth = {
+ .pos = {(float)config.SCREEN_WIDTH / 2, (float)config.SCREEN_HEIGHT / 2 },
+ .radius = 20,
+ .mass = 15000,
+ .velocity = { 0.0f, 0.0f },
+ .force = {0.0f, 0.0f},
+ BLUE
+ };
- Object objects[] = {object0, object1};
- int objectNum = sizeof(objects) / sizeof(Object);
+ Ball *balls[] = {&earth, &luna, &potato};
while (!WindowShouldClose())
{
- doUpdate(&vectorField, objects, objectNum);
- doDrawing(&vectorField, colSize, rowSize, objects, objectNum);
+ doUpdate(balls, 3, physics);
+ doDrawing(balls, 3);
}
CloseWindow();
@@ -102,81 +80,66 @@ int main(void)
return 0;
}
-void Initialize(Config config) {
+void doInitialization(InitConfig config) {
InitWindow(config.SCREEN_WIDTH, config.SCREEN_HEIGHT, config.TITLE);
SetTargetFPS(config.TARGET_FPS);
}
-void MemAllocFailed(char *source) {
- printf("Memory allocation for %s failed", source);
- exit(42);
-}
-
-//float getRndAngle() {
-// float nMax = 360;
-// return (float)rand() / ((float)RAND_MAX / nMax); // NOLINT(cert-msc30-c, cert-msc50-cpp)
+//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);
//}
-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;
- }
- }
+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 doUpdate(VectorField *vectorField, Object *objects, int objectNum) {
- float forceConstant = 5000.0f;
+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);
+}
+
+void doUpdate(Ball **balls, int totalBalls, Physics physics) {
float dt = GetFrameTime();
- 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;
+ 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);
}
- 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(VectorField *vectorField, int colSize, int rowSize, Object *objects, int objectNum) {
+void doDrawing(Ball **balls, int totalBalls) {
BeginDrawing();
ClearBackground(BLACK);
- 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);
+ for (int i = 0; i < totalBalls; i++) {
+ Ball *ball = balls[i];
+ DrawCircleV(ball->pos, ball->radius, ball->color);
}
EndDrawing();