From 7dbd638ac19bc484077957fb90c1805f6af1f8d2 Mon Sep 17 00:00:00 2001 From: zeefaad Date: Sun, 28 Dec 2025 10:42:48 +0100 Subject: [PATCH] ui amelioration --- main.c | 167 +++++++++++++++++++++++++++++++++++------------------- michelson | Bin 121064 -> 121240 bytes 2 files changed, 109 insertions(+), 58 deletions(-) diff --git a/main.c b/main.c index 07a220b..cfc48e9 100644 --- a/main.c +++ b/main.c @@ -1,11 +1,14 @@ #include "raylib.h" #include -#include - #define RAYGUI_IMPLEMENTATION #include "raygui.h" #define UI_WIDTH 400 +#define COLOR_BG (Color){ 25, 25, 30, 255 } +#define COLOR_PANEL (Color){ 40, 40, 45, 255 } +#define COLOR_ACCENT (Color){ 0, 120, 240, 255 } +#define COLOR_TEXT_DIM (Color){ 180, 180, 190, 255 } +#define COLOR_TEXT_SEC (Color){ 160, 160, 170, 255 } typedef struct { float d1; @@ -32,11 +35,19 @@ Color WavelengthToColor(float lambda) { return (Color){(unsigned char)(r * factor * 255), (unsigned char)(g * factor * 255), (unsigned char)(b * factor * 255), 255}; } +void DrawLaserBeam(Vector2 start, Vector2 end, Color color, float thickness) { + DrawLineEx(start, end, thickness * 4.0f, Fade(color, 0.15f)); + DrawLineEx(start, end, thickness * 2.0f, Fade(color, 0.4f)); + DrawLineEx(start, end, thickness, color); +} + void DrawInterferenceView(Michelson *mic, Rectangle rec) { - DrawText("ECRAN", rec.x, rec.y - 30, 20, WHITE); + DrawRectangleRec((Rectangle){rec.x - 4, rec.y - 30, rec.width + 8, rec.height + 34}, COLOR_PANEL); + //DrawText("ECRAN", rec.x, rec.y - 30, 20, WHITE); + DrawText("ECRAN", rec.x, rec.y - 26, 20, COLOR_TEXT_DIM); DrawRectangleRec(rec, BLACK); - DrawRectangleLinesEx(rec, 2, DARKGRAY); + DrawRectangleLinesEx(rec, 1, Fade(COLOR_ACCENT, 0.3f)); Color baseColor = WavelengthToColor(mic->lambda); @@ -45,6 +56,8 @@ void DrawInterferenceView(Michelson *mic, Rectangle rec) { int cx = rec.x + rec.width / 2; int cy = rec.y + rec.height / 2; + + float K = PI / mic->lambda; // Dessin pixel par pixel lent... => faire avec gpu for (int y = rec.y; y < rec.y + rec.height; y++) { @@ -53,6 +66,8 @@ void DrawInterferenceView(Michelson *mic, Rectangle rec) { float relY = (float)(y - cy); float radiusSq = relX * relX + relY * relY; + //if (radiusSq > (rec.width / 2.0f - 5) * (rec.width / 2.0f - 5)) continue; + // Diff de marche lamme d'air 2 * e cos(i) mais petits angles => cos(i) ~ 1 - i^2/2 mais i ~ r/f et r^2 = x^2 + y^2 float ringFactor = radiusSq * 0.065f; // Diff de marche dut au coin d'air @@ -61,7 +76,7 @@ void DrawInterferenceView(Michelson *mic, Rectangle rec) { float currDelta = deltaLnm - ringFactor + wDelta; // Formule de Fresnel : I = I_0 * cos^2(phi) - float phase = (PI * currDelta) / mic->lambda; + float phase = currDelta * K; float intensity = cosf(phase); intensity = intensity * intensity; @@ -70,6 +85,8 @@ void DrawInterferenceView(Michelson *mic, Rectangle rec) { DrawPixel(x, y, pixColor); } } + + DrawRectangleLinesEx(rec, 2, COLOR_PANEL); // croix centre DrawLine(cx - 10, cy, cx + 10, cy, Fade(WHITE, 0.5f)); @@ -80,37 +97,48 @@ void DrawMichelsonSchema (Michelson *mic) { Vector2 c = mic->center; Color laserColor = WavelengthToColor(mic->lambda); - float thickness = 4.0f; + float thickness = 3.0f; float sourceLen = 450.0f; float screenLen = 450.0f; float mirrorSize = 140.0f; - // Source - Vector2 startSource = {c.x - sourceLen, c.y}; - DrawLineEx(startSource, c, thickness, laserColor); - DrawRectangle(startSource.x - 20, startSource.y - 15, 20, 30, DARKGRAY); - DrawText("Source", startSource.x - 30, startSource.y - 40, 20, LIGHTGRAY); + // Laser + BeginBlendMode(BLEND_ADDITIVE); + // Source + Vector2 startSource = {c.x - sourceLen, c.y}; + DrawLaserBeam(startSource, c, laserColor, thickness); - // Miroir M2 (fixe) - Vector2 posM2 = {c.x + mic->d2, c.y}; - DrawLineEx(c, posM2, thickness, laserColor); - DrawLineEx(c, (Vector2){c.x, c.y + screenLen}, thickness, Fade(laserColor, 0.6f)); + // Miroir M2 (fixe) + Vector2 posM2 = {c.x + mic->d2, c.y}; + DrawLaserBeam(c, posM2, laserColor, thickness); + + // Miroir M1 (mobile) + Vector2 posM1 = {c.x, c.y - mic->d1}; + DrawLaserBeam(c, posM1, laserColor, thickness); + + // Projection rayon sur écran (corection tangente) + float angleRad = -(mic->angleM1 * 2.0f) * (PI / 180.0f); + float yScreen = c.y + screenLen; + float vertDist = yScreen - posM1.y; + float xOff = vertDist * tanf(angleRad); + Vector2 endPointRetour = { posM1.x + xOff, yScreen }; + DrawLaserBeam(posM1, endPointRetour, Fade(laserColor, 0.6f), thickness); + + Vector2 endPointM2 = {c.x, c.y + screenLen}; + DrawLaserBeam(c, endPointM2, Fade(laserColor, 0.5f), thickness); + EndBlendMode(); + + // Source + DrawRectangle(startSource.x - 30, startSource.y - 20, 30, 40, DARKGRAY); + DrawRectangleLines(startSource.x - 30, startSource.y - 20, 30, 40, GRAY); + DrawText("Source", startSource.x - 50, startSource.y - 50, 20, LIGHTGRAY); + + // M2 DrawRectangle(posM2.x, posM2.y - (mirrorSize / 2), 12, mirrorSize, LIGHTGRAY); DrawRectangle(posM2.x, posM2.y - (mirrorSize / 2) + 2, 4, mirrorSize - 4, WHITE); DrawText("M2", posM2.x + 20, posM2.y - 10, 20, GRAY); - // Miroir M1 (mobile) - Vector2 posM1 = {c.x, c.y - mic->d1}; - DrawLineEx(c, posM1, thickness, laserColor); - - // Projection rayon sur écran (corection tangente) - float angleRad = -(mic->angleM1 * 2.0f) * (PI / 180.0f); - float yScreen = c.y + screenLen; - float vertDist = yScreen - posM1.y; - float xOff = vertDist * tanf(angleRad); - Vector2 endPointRetour = { posM1.x + xOff, yScreen }; - DrawLineEx(posM1, endPointRetour, thickness, Fade(laserColor, 0.6f)); - + // M1 Rectangle recM1 = {posM1.x, posM1.y, mirrorSize, 12.0f}; Vector2 originM1 = {mirrorSize / 2, 6.0f}; DrawRectanglePro(recM1, originM1, mic->angleM1, LIGHTGRAY); @@ -121,68 +149,87 @@ void DrawMichelsonSchema (Michelson *mic) { // Séparatrice float sepLen = 220.0f; - Rectangle sepRec = {c.x, c.y, 4.0f, sepLen}; + Rectangle sepRec = {c.x, c.y, 6.0f, sepLen}; Vector2 sepOrigin = {2.0f, sepLen / 2}; DrawRectanglePro(sepRec, sepOrigin, -45.0f, Fade(SKYBLUE, 0.4f)); - DrawRectanglePro((Rectangle){c.x, c.y, 1.0f, sepLen}, (Vector2){0.5f, sepLen / 2}, -45.0f, Fade(WHITE, 0.5f)); + DrawRectanglePro((Rectangle){c.x, c.y, 2.0f, sepLen}, (Vector2){1.0f, sepLen / 2}, -45.0f, Fade(WHITE, 0.4f)); - DrawRectangle(c.x - 300, yScreen, 600, 15, DARKGRAY); - DrawText("Ecran", c.x - 20, yScreen + 20, 20, GRAY); + DrawRectangle(c.x - 300, yScreen, 600, 15, COLOR_PANEL); + DrawText("Ecran", c.x - 20, yScreen + 20, 20, COLOR_TEXT_DIM); } void DrawControlPanel(Michelson *mic) { - DrawRectangle(0, 0, UI_WIDTH, GetScreenHeight(), (Color){30, 30, 30, 255}); - DrawLine(UI_WIDTH, 0, UI_WIDTH, GetScreenHeight(), WHITE); + DrawRectangle(0, 0, UI_WIDTH, GetScreenHeight(), Fade(COLOR_PANEL, 0.95f)); + DrawLine(UI_WIDTH, 0, UI_WIDTH, GetScreenHeight(), Fade(WHITE, 0.1f)); int startX = 30; int startY = 30; - int buttonWidth = 60; + int buttonWidth = 70; int spacing = 20; int contentWidth = UI_WIDTH - 60; int sliderWidth = contentWidth - buttonWidth - spacing - 15; - GuiSetStyle(DEFAULT, TEXT_SIZE, 18); - GuiSetStyle(DEFAULT, BASE_COLOR_NORMAL, 0x404040FF); - GuiSetStyle(DEFAULT, BORDER_COLOR_NORMAL, 0x808080FF); - GuiSetStyle(DEFAULT, TEXT_COLOR_NORMAL, 0xFFFFFFFF); + GuiSetStyle(DEFAULT, TEXT_SIZE, 16); + GuiSetStyle(DEFAULT, BASE_COLOR_NORMAL, 0x2D2D2DFF); // Gris foncé boutons + GuiSetStyle(DEFAULT, BASE_COLOR_FOCUSED, 0x454545FF); // Gris clair hover + GuiSetStyle(DEFAULT, BASE_COLOR_PRESSED, 0x1A1A1AFF); // Très foncé click + GuiSetStyle(DEFAULT, TEXT_COLOR_NORMAL, 0xFFFFFFFF); // Texte blanc + GuiSetStyle(DEFAULT, BORDER_COLOR_NORMAL, 0x505050FF); + GuiSetStyle(DEFAULT, BORDER_COLOR_FOCUSED, 0x0078D7FF); // Bordures bleues (focus) + GuiSetStyle(DEFAULT, BACKGROUND_COLOR, 0x1E1E1EFF); DrawText("PARAMETRES", startX, startY, 30, WHITE); + DrawLine(startX, startY + 35, startX + contentWidth, startY + 35, COLOR_ACCENT); // Sliders - startY += 80; - DrawText(TextFormat("Longueur d'onde: %.0f nm", mic->lambda), startX, startY, 20, LIGHTGRAY); - GuiSlider((Rectangle){startX, startY + 30, contentWidth - 45, 30}, NULL, NULL, &mic->lambda, 380, 780); - DrawRectangle(startX + contentWidth - 35, startY + 30, 35, 30, WavelengthToColor(mic->lambda)); + startY += 70; + DrawText(TextFormat("Longueur d'onde: %.0f nm", mic->lambda), startX, startY, 20, COLOR_TEXT_SEC); + GuiSlider((Rectangle){startX, startY + 30, contentWidth - 45, 25}, NULL, NULL, &mic->lambda, 380, 780); + DrawRectangle(startX + contentWidth - 35, startY + 30, 35, 25, WavelengthToColor(mic->lambda)); - startY += 100; + startY += 90; DrawText(TextFormat("Position M1 (d1): %.1f um", mic->d1), startX, startY, 20, ORANGE); - GuiSlider((Rectangle){startX, startY + 30, sliderWidth, 30}, NULL, NULL, &mic->d1, 100, 600); - if (GuiButton((Rectangle){startX + sliderWidth + spacing + 15, startY + 30, buttonWidth, 30}, "Egal")) mic->d1 = mic->d2; + GuiSlider((Rectangle){startX, startY + 30, sliderWidth, 25}, NULL, NULL, &mic->d1, 100, 600); + if (GuiButton((Rectangle){startX + sliderWidth + spacing + 15, startY + 30, buttonWidth, 25}, "Egal")) mic->d1 = mic->d2; - startY += 100; + startY += 90; DrawText(TextFormat("Inclinaison M1: %.2f deg", mic->angleM1), startX, startY, 20, ORANGE); - GuiSlider((Rectangle){startX, startY + 30, sliderWidth, 30}, "-1", "+1", &mic->angleM1, -1.0f, 1.0f); - if (GuiButton((Rectangle){startX + sliderWidth + spacing + 15, startY + 30, buttonWidth, 30}, "0.0")) mic->angleM1 = 0.0f; + GuiSlider((Rectangle){startX, startY + 30, sliderWidth, 25}, "-1", "+1", &mic->angleM1, -1.0f, 1.0f); + if (GuiButton((Rectangle){startX + sliderWidth + spacing + 15, startY + 30, buttonWidth, 25}, "0.0")) mic->angleM1 = 0.0f; - const char* modeTxt = (fabs(mic->angleM1) < 0.01f) ? "MODE: LAME D'AIR" : "MODE: COIN D'AIR"; - Color modeColor = (fabs(mic->angleM1) < 0.01f) ? SKYBLUE : GREEN; - DrawText(modeTxt, startX, startY + 75, 20, modeColor); + bool isLameAir = (fabs(mic->angleM1) < 0.01f); + const char* modeTxt = isLameAir ? "MODE: LAME D'AIR" : "MODE: COIN D'AIR"; + Color modeColor = isLameAir ? SKYBLUE : GREEN; + + DrawRectangle(startX, startY + 70, contentWidth, 30, Fade(modeColor, 0.2f)); + DrawRectangleLines(startX, startY + 70, contentWidth, 30, modeColor); + DrawText(modeTxt, startX + 10, startY + 78, 18, modeColor); - startY += 140; - DrawRectangleLines(startX - 10, startY - 10, contentWidth + 20, 100, GRAY); - DrawText("Données", startX, startY, 20, LIGHTGRAY); + // Données + startY += 150; + DrawLine(startX, startY - 20, startX + contentWidth, startY - 20, GRAY); + DrawText("DONNEES TEMPS REEL", startX, startY, 20, GRAY); float delta = 2 * (mic->d1 - mic->d2); - DrawText(TextFormat("Delta = %.2f um", delta), startX, startY + 35, 22, WHITE); + DrawText(TextFormat("Delta = %.2f um", delta), startX, startY + 35, 20, WHITE); float p = (delta * 1000.0f) / mic->lambda; - DrawText(TextFormat("Ordre p = %.2f", p), startX, startY + 65, 22, LIGHTGRAY); + DrawText(TextFormat("Ordre p = %.2f", p), startX, startY + 65, 20, WHITE); + + int bottomY = GetScreenHeight() - 40; + DrawLine(0, bottomY, UI_WIDTH, bottomY, Fade(WHITE, 0.1f)); + + int fps = GetFPS(); + Color fpsColor = (fps >= 100) ? COLOR_ACCENT : (fps >= 60 ? GREEN : (fps >= 30 ? ORANGE : RED)); + + DrawText("STATUT:", startX, bottomY + 12, 20, COLOR_TEXT_DIM); + DrawText(TextFormat("%i FPS", fps), startX + 100, bottomY + 12, 20, fpsColor); } int main () { SetConfigFlags(FLAG_MSAA_4X_HINT); InitWindow(1920, 1080, "Interferometre de Michelson"); - SetTargetFPS(60); + SetTargetFPS(144); Michelson mic = {0}; mic.center = (Vector2){ UI_WIDTH + (1920 - UI_WIDTH) / 2.0f - 100, 1080 / 2.0f }; @@ -196,7 +243,11 @@ int main () { while (!WindowShouldClose()) { BeginDrawing(); - ClearBackground(BLACK); + ClearBackground(COLOR_BG); + // Grille fond + for(int i=UI_WIDTH; i<1920; i+=100) DrawLine(i, 0, i, 1080, Fade(WHITE, 0.05f)); + for(int i=0; i<1080; i+=100) DrawLine(UI_WIDTH, i, 1920, i, Fade(WHITE, 0.05f)); + DrawMichelsonSchema(&mic); DrawControlPanel(&mic); DrawInterferenceView(&mic, screenViewBounds); diff --git a/michelson b/michelson index a6fcbeccce199d5c3375f84c4b8e0032bfeef4d8..e5b24af5519e9c5b3e5847c5a847ce17fd2dc9af 100755 GIT binary patch delta 25715 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 WDvS57ur}Vh^D13~iC*8Z;Qt3!m-Dj# delta 23971 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 z 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