diff --git a/main.c b/main.c index 75dbf00..07a220b 100644 --- a/main.c +++ b/main.c @@ -29,12 +29,51 @@ Color WavelengthToColor(float lambda) { else if (lambda >= 380 && lambda <= 645) factor = 1.0f; else if (lambda > 700 && lambda <= 780) factor = 0.3f + 0.7f * (780 - lambda) / (780 - 700); - return (Color){ - (unsigned char)(r * factor * 255), - (unsigned char)(g * factor * 255), - (unsigned char)(b * factor * 255), - 255 - }; + return (Color){(unsigned char)(r * factor * 255), (unsigned char)(g * factor * 255), (unsigned char)(b * factor * 255), 255}; +} + +void DrawInterferenceView(Michelson *mic, Rectangle rec) { + DrawText("ECRAN", rec.x, rec.y - 30, 20, WHITE); + + DrawRectangleRec(rec, BLACK); + DrawRectangleLinesEx(rec, 2, DARKGRAY); + + Color baseColor = WavelengthToColor(mic->lambda); + + // Diff de marche du à l'axe (2 * e) + micro -> nano + float deltaLnm = 2.0f * (mic->d1 - mic->d2) * 1000.0f; + + int cx = rec.x + rec.width / 2; + int cy = rec.y + rec.height / 2; + + // Dessin pixel par pixel lent... => faire avec gpu + for (int y = rec.y; y < rec.y + rec.height; y++) { + for (int x = rec.x; x < rec.x + rec.width; x++) { + float relX = (float)(x - cx); + float relY = (float)(y - cy); + float radiusSq = relX * relX + relY * relY; + + // 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 + float wDelta = relX * mic->angleM1 * 200.0f; + + float currDelta = deltaLnm - ringFactor + wDelta; + + // Formule de Fresnel : I = I_0 * cos^2(phi) + float phase = (PI * currDelta) / mic->lambda; + float intensity = cosf(phase); + intensity = intensity * intensity; + + Color pixColor = {(unsigned char)(baseColor.r * intensity), (unsigned char)(baseColor.g * intensity), (unsigned char)(baseColor.b * intensity), 255 }; + + DrawPixel(x, y, pixColor); + } + } + + // croix centre + DrawLine(cx - 10, cy, cx + 10, cy, Fade(WHITE, 0.5f)); + DrawLine(cx, cy - 10, cx, cy + 10, Fade(WHITE, 0.5f)); } void DrawMichelsonSchema (Michelson *mic) { @@ -42,50 +81,45 @@ void DrawMichelsonSchema (Michelson *mic) { Color laserColor = WavelengthToColor(mic->lambda); float thickness = 4.0f; - float armLengthSource = 450.0f; - float armLengthScreen = 450.0f; + float sourceLen = 450.0f; + float screenLen = 450.0f; float mirrorSize = 140.0f; - Vector2 startSource = {c.x - armLengthSource, c.y}; + // 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); + // Miroir M2 (fixe) Vector2 posM2 = {c.x + mic->d2, c.y}; - DrawLineEx(c, posM2, thickness, laserColor); - DrawLineEx(c, (Vector2){c.x, c.y + armLengthScreen}, thickness, Fade(laserColor, 0.6f)); - + DrawLineEx(c, (Vector2){c.x, c.y + screenLen}, thickness, Fade(laserColor, 0.6f)); 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); - float angleRad = (mic->angleM1 * 2.0f) * (PI / 180.0f); - float yScreen = c.y + armLengthScreen; - float verticalDist = yScreen - posM1.y; - float xOffset = verticalDist * tanf(angleRad); - - Vector2 endPointRetour = { - posM1.x + xOffset, - yScreen - }; - + // 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)); Rectangle recM1 = {posM1.x, posM1.y, mirrorSize, 12.0f}; Vector2 originM1 = {mirrorSize / 2, 6.0f}; DrawRectanglePro(recM1, originM1, mic->angleM1, LIGHTGRAY); - Rectangle recM1Face = {posM1.x, posM1.y, mirrorSize - 4, 4.0f}; Vector2 originM1Face = {(mirrorSize - 4) / 2, 6.0f}; DrawRectanglePro(recM1Face, originM1Face, mic->angleM1, WHITE); - DrawText("M1", posM1.x - 40, posM1.y - 30, 20, ORANGE); + // Séparatrice float sepLen = 220.0f; Rectangle sepRec = {c.x, c.y, 4.0f, sepLen}; Vector2 sepOrigin = {2.0f, sepLen / 2}; @@ -102,7 +136,6 @@ void DrawControlPanel(Michelson *mic) { int startX = 30; int startY = 30; - int buttonWidth = 60; int spacing = 20; int contentWidth = UI_WIDTH - 60; @@ -115,28 +148,21 @@ void DrawControlPanel(Michelson *mic) { DrawText("PARAMETRES", startX, startY, 30, WHITE); + // 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 += 100; - DrawText(TextFormat("Position M1 (d1): %.1f", mic->d1), startX, startY, 20, ORANGE); - + 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; - } + if (GuiButton((Rectangle){startX + sliderWidth + spacing + 15, startY + 30, buttonWidth, 30}, "Egal")) mic->d1 = mic->d2; startY += 100; DrawText(TextFormat("Inclinaison M1: %.2f deg", mic->angleM1), startX, startY, 20, ORANGE); - - GuiSlider((Rectangle){startX, startY + 30, sliderWidth, 30}, "-5", "+5", &mic->angleM1, -5.0f, 5.0f); - - if (GuiButton((Rectangle){startX + sliderWidth + spacing + 15, startY + 30, buttonWidth, 30}, "0.0")) { - mic->angleM1 = 0.0f; - } + 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; 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; @@ -144,34 +170,36 @@ void DrawControlPanel(Michelson *mic) { startY += 140; DrawRectangleLines(startX - 10, startY - 10, contentWidth + 20, 100, GRAY); - DrawText("Données temps réel", startX, startY, 20, LIGHTGRAY); + DrawText("Données", startX, startY, 20, LIGHTGRAY); float delta = 2 * (mic->d1 - mic->d2); - DrawText(TextFormat("Delta (m) = %.2f", delta), startX, startY + 35, 22, WHITE); + DrawText(TextFormat("Delta = %.2f um", delta), startX, startY + 35, 22, WHITE); - float p = delta / (mic->lambda / 10.0f); - DrawText(TextFormat("Ordre p = %.2f", p), startX, startY + 65, 22, LIGHTGRAY); + float p = (delta * 1000.0f) / mic->lambda; + DrawText(TextFormat("Ordre p = %.2f", p), startX, startY + 65, 22, LIGHTGRAY); } int main () { SetConfigFlags(FLAG_MSAA_4X_HINT); - InitWindow(1920, 1080, "Interferometre de Michelson - Full HD"); + InitWindow(1920, 1080, "Interferometre de Michelson"); SetTargetFPS(60); Michelson mic = {0}; - mic.center = (Vector2){ UI_WIDTH + (1920 - UI_WIDTH) / 2.0f, 1080 / 2.0f }; - + mic.center = (Vector2){ UI_WIDTH + (1920 - UI_WIDTH) / 2.0f - 100, 1080 / 2.0f }; mic.d1 = 250.0f; mic.d2 = 250.0f; - - mic.lambda = 500.0f; + mic.lambda = 550.0f; mic.angleM1 = 0.0f; + Rectangle screenViewBounds = {1920 - 530, 50, 500, 500}; + //Rectangle screenViewBounds = {400, 0, 1080, 1080}; + while (!WindowShouldClose()) { BeginDrawing(); ClearBackground(BLACK); DrawMichelsonSchema(&mic); DrawControlPanel(&mic); + DrawInterferenceView(&mic, screenViewBounds); EndDrawing(); } CloseWindow(); diff --git a/michelson b/michelson new file mode 100755 index 0000000..a6fcbec Binary files /dev/null and b/michelson differ