multiple labmda

This commit is contained in:
2025-12-28 17:04:49 +01:00
parent d8e178fe06
commit 911deefbf5
3 changed files with 189 additions and 47 deletions

187
main.c
View File

@ -10,10 +10,14 @@
#define COLOR_TEXT_DIM (Color){ 180, 180, 190, 255 }
#define COLOR_TEXT_SEC (Color){ 160, 160, 170, 255 }
#define MAX_WAVELENGTHS 10
typedef struct {
float d1;
float d2;
float lambda;
float lambdas[MAX_WAVELENGTHS];
int lambdasCount;
int selectedLambdaIndex;
float angleM1;
float angleM1_Y;
Vector2 center;
@ -81,7 +85,18 @@ void DrawInterferenceViewGPU(Michelson *mic, Rectangle rec, Shader shader, bool
SetShaderValue(shader, GetShaderLocation(shader, "d1"), &mic->d1, SHADER_UNIFORM_FLOAT);
SetShaderValue(shader, GetShaderLocation(shader, "d2"), &d2_effective, SHADER_UNIFORM_FLOAT);
SetShaderValue(shader, GetShaderLocation(shader, "lambda"), &mic->lambda, SHADER_UNIFORM_FLOAT);
float lambdasData[MAX_WAVELENGTHS];
for(int i = 0; i < MAX_WAVELENGTHS; i++) {
if (i < mic->lambdasCount) lambdasData[i] = mic->lambdas[i];
else lambdasData[i] = 0.0f;
}
int locLambdas = GetShaderLocation(shader, "lambdas");
int locCount = GetShaderLocation(shader, "lambdasCount");
SetShaderValueV(shader, locLambdas, lambdasData, SHADER_UNIFORM_FLOAT, MAX_WAVELENGTHS);
SetShaderValue(shader, locCount, &mic->lambdasCount, SHADER_UNIFORM_INT);
//SetShaderValue(shader, GetShaderLocation(shader, "lambda"), &mic->lambda, SHADER_UNIFORM_FLOAT);
SetShaderValue(shader, GetShaderLocation(shader, "angleM1"), &mic->angleM1, SHADER_UNIFORM_FLOAT);
SetShaderValue(shader, GetShaderLocation(shader, "angleM1_Y"), &mic->angleM1_Y, SHADER_UNIFORM_FLOAT);
SetShaderValue(shader, GetShaderLocation(shader, "zoom"), &zoom, SHADER_UNIFORM_FLOAT);
@ -102,17 +117,28 @@ void DrawInterferenceViewGPU(Michelson *mic, Rectangle rec, Shader shader, bool
void DrawMichelsonSchema (Michelson *mic) {
Vector2 c = mic->center;
Color laserColor = WavelengthToColor(mic->lambda);
//Color laserColor = WavelengthToColor(mic->lambda);
float thickness = 3.0f;
float sourceLen = 450.0f;
float screenLen = 450.0f;
float mirrorSize = 140.0f;
Vector2 startSource = {c.x - sourceLen, c.y};
Vector2 posM2 = {c.x + mic->d2, c.y};
Vector2 posM1 = {c.x, c.y - mic->d1};
Vector2 endPointM2 = {c.x, c.y + screenLen};
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 };
// Laser
BeginBlendMode(BLEND_ADDITIVE);
/*
// Source
Vector2 startSource = {c.x - sourceLen, c.y};
DrawLaserBeam(startSource, c, laserColor, thickness);
// Miroir M2 (fixe)
@ -133,6 +159,24 @@ void DrawMichelsonSchema (Michelson *mic) {
Vector2 endPointM2 = {c.x, c.y + screenLen};
DrawLaserBeam(c, endPointM2, Fade(laserColor, 0.5f), thickness);
*/
float alphaFactor = 1.0f / (float)(mic->lambdasCount > 0 ? mic->lambdasCount : 1);
if(alphaFactor < 0.3f) alphaFactor = 0.3f; // Min de visibilité
for(int i=0; i<mic->lambdasCount; i++) {
Color laserColor = WavelengthToColor(mic->lambdas[i]);
laserColor = Fade(laserColor, alphaFactor);
// Source -> Centre
DrawLaserBeam(startSource, c, laserColor, thickness);
// Centre -> Miroir M2 (fixe)
DrawLaserBeam(c, posM2, laserColor, thickness);
// Centre -> Miroir M1 (mobile)
DrawLaserBeam(c, posM1, laserColor, thickness);
// Retour M1 -> Ecran
DrawLaserBeam(posM1, endPointRetour, Fade(laserColor, 0.6f), thickness);
// Retour M2 -> Ecran
DrawLaserBeam(c, endPointM2, Fade(laserColor, 0.5f), thickness);
}
EndBlendMode();
// Source
@ -213,48 +257,124 @@ void DrawControlPanel(Michelson *mic) {
// Longueur d'onde
startY += 80;
DrawText(TextFormat("Longueur d'onde: %.0f nm", mic->lambda), startX, startY, 20, COLOR_TEXT_SEC);
DrawText("SPECTRE (Clic Droit: +/-)", startX, startY, 20, COLOR_TEXT_SEC);
float stepLambda = speedMode ? 10.0f : 1.0f;
if (GuiButtonRepeat((Rectangle){startX, startY + 30, btnSize, 25}, "-", shouldRepeat)) mic->lambda -= stepLambda;
Rectangle spectrumRect = {startX + btnSize + 5, startY + 30, spectrumWidth, 25};
int spectrumHeight = 35;
Rectangle spectrumRect = {startX, startY + 25, contentWidth, spectrumHeight};
// spectre
for (int i = 0; i < spectrumRect.width; i++) {
float prog = (float)i / spectrumRect.width;
float l = 380.0f + prog * (780.0f - 380.0f);
Color c = WavelengthToColor(l);
DrawLine(spectrumRect.x + i, spectrumRect.y, spectrumRect.x + i, spectrumRect.y + spectrumRect.height, c);
DrawLine(spectrumRect.x + i, spectrumRect.y, spectrumRect.x + i, spectrumRect.y + spectrumRect.height, WavelengthToColor(l));
}
DrawRectangleLinesEx(spectrumRect, 1, DARKGRAY);
DrawRectangleLinesEx(spectrumRect, 1, GRAY);
if (CheckCollisionPointRec(GetMousePosition(), spectrumRect)) {
Vector2 mousePos = GetMousePosition();
float stepLambda = speedMode ? 10.0f : 1.0f;
if (CheckCollisionPointRec(mousePos, spectrumRect)) {
float mouseRatio = (mousePos.x - spectrumRect.x) / spectrumRect.width;
float mouseLambda = 380.0f + mouseRatio * (780.0f - 380.0f);
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) {
float mouseX = GetMouseX() - spectrumRect.x;
float ratio = mouseX / spectrumRect.width;
mic->lambda = 380.0f + ratio * (780.0f - 380.0f);
if (mic->selectedLambdaIndex >= 0 && mic->selectedLambdaIndex < mic->lambdasCount) {
mic->lambdas[mic->selectedLambdaIndex] = mouseLambda;
}
}
if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) {
int foundIdx = -1;
for(int i = 0; i < mic->lambdasCount; i++) {
if (fabs(mic->lambdas[i] - mouseLambda) < 15.0f) {
foundIdx = i; break;
}
}
if (foundIdx != -1) {
if (mic->lambdasCount > 1) {
for(int k=foundIdx; k < mic->lambdasCount - 1; k++) {
mic->lambdas[k] = mic->lambdas[k+1];
}
mic->lambdasCount--;
mic->selectedLambdaIndex = 0;
}
} else {
if (mic->lambdasCount < MAX_WAVELENGTHS) {
mic->lambdas[mic->lambdasCount] = mouseLambda;
mic->selectedLambdaIndex = mic->lambdasCount;
mic->lambdasCount++;
}
}
}
}
float currentRatio = (mic->lambda - 380.0f) / (780.0f - 380.0f);
if (currentRatio < 0) currentRatio = 0;
if (currentRatio > 1) currentRatio = 1;
//curseur
for (int i = 0; i < mic->lambdasCount; i++) {
if (mic->lambdas[i] < 380) mic->lambdas[i] = 380;
if (mic->lambdas[i] > 780) mic->lambdas[i] = 780;
float cursorX = spectrumRect.x + currentRatio * spectrumRect.width;
float ratio = (mic->lambdas[i] - 380.0f) / (780.0f - 380.0f);
float lineX = spectrumRect.x + ratio * spectrumRect.width;
bool isSel = (i == mic->selectedLambdaIndex);
DrawLine(cursorX - 1, spectrumRect.y, cursorX - 1, spectrumRect.y + spectrumRect.height, BLACK);
DrawLine(cursorX + 1, spectrumRect.y, cursorX + 1, spectrumRect.y + spectrumRect.height, BLACK);
DrawLine(cursorX, spectrumRect.y, cursorX, spectrumRect.y + spectrumRect.height, WHITE);
Color lineCol = isSel ? WHITE : GRAY;
float thick = isSel ? 3.0f : 2.0f;
if (GuiButtonRepeat((Rectangle){startX + btnSize + spectrumWidth + 10, startY + 30, btnSize, 25}, "+", shouldRepeat)) mic->lambda += stepLambda;
DrawLineEx((Vector2){lineX, spectrumRect.y}, (Vector2){lineX, spectrumRect.y + spectrumRect.height}, thick, lineCol);
if (mic->lambda < 380) mic->lambda = 380;
if (mic->lambda > 780) mic->lambda = 780;
if(isSel) DrawTriangle((Vector2){lineX-5, spectrumRect.y-6}, (Vector2){lineX+5, spectrumRect.y-6}, (Vector2){lineX, spectrumRect.y}, WHITE);
}
// selction labmda
startY += spectrumHeight + 35;
if (mic->selectedLambdaIndex >= mic->lambdasCount)
mic->selectedLambdaIndex = 0;
float* currentVal = &mic->lambdas[mic->selectedLambdaIndex];
if (GuiButtonRepeat((Rectangle){startX, startY, 40, 30}, "-", shouldRepeat))
*currentVal -= stepLambda;
DrawRectangle(startX + 45, startY, contentWidth - 90, 30, COLOR_PANEL);
DrawRectangleLines(startX + 45, startY, contentWidth - 90, 30, GRAY);
Color activeCol = WavelengthToColor(*currentVal);
DrawRectangle(startX + 50, startY + 5, 20, 20, activeCol);
DrawText(TextFormat("%.1f nm", *currentVal), startX + 80, startY + 5, 20, WHITE);
if (GuiButtonRepeat((Rectangle){startX + contentWidth - 40, startY, 40, 30}, "+", shouldRepeat))
*currentVal += stepLambda;
// lambda acrifs
startY += 45;
DrawText("Longueurs d'onde actives :", startX, startY, 20, GRAY);
startY += 25;
int cols = 5;
int btnW = (contentWidth - (cols - 1) * 5) / cols;
int btnH = 30;
for(int i = 0; i < mic->lambdasCount; i++) {
int r = i / cols;
int c = i % cols;
Rectangle rectBtn = {startX + c * (btnW + 5), startY + r * (btnH + 5), btnW, btnH};
bool isSel = (i == mic->selectedLambdaIndex);
Color cVal = WavelengthToColor(mic->lambdas[i]);
if (GuiButton(rectBtn, TextFormat("%.0f", mic->lambdas[i])))
mic->selectedLambdaIndex = i;
if (isSel)
DrawRectangleLinesEx(rectBtn, 2, WHITE);
DrawRectangle(rectBtn.x + 2, rectBtn.y + 2, 5, rectBtn.height - 4, cVal);
}
int rows = (mic->lambdasCount + cols - 1) / cols;
startY += (rows * (btnH + 5)) + 20;
// Pos M1
startY += 90;
startY += 0;
DrawText(TextFormat("Position M1 : %.2f um", mic->d1), startX, startY, 20, ORANGE);
// Pas des + et -
@ -316,8 +436,9 @@ void DrawControlPanel(Michelson *mic) {
float delta = 2 * (mic->d1 - mic->d2);
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, 20, WHITE);
float refLambda = mic->lambdas[mic->selectedLambdaIndex];
float p = (delta * 1000.0f) / refLambda;
DrawText(TextFormat("Ordre p (sel) = %.2f", p), startX, startY + 65, 20, WHITE);
// Bas
int bottomY = GetScreenHeight() - 40;
@ -331,7 +452,7 @@ void DrawControlPanel(Michelson *mic) {
int main () {
SetConfigFlags(FLAG_MSAA_4X_HINT);
InitWindow(1920, 1080, "Interferometre de Michelson");
SetTargetFPS(144);
SetTargetFPS(10044);
Shader shader = LoadShader(0, "michelson.frag");
@ -339,7 +460,9 @@ int main () {
mic.center = (Vector2){ UI_WIDTH + (1920 - UI_WIDTH) / 2.0f - 100, 1080 / 2.0f };
mic.d1 = 250.0f;
mic.d2 = 250.0f;
mic.lambda = 550.0f;
mic.lambdas[0] = 550.0f;
mic.lambdasCount = 1;
mic.selectedLambdaIndex = 0;
mic.angleM1 = 0.0f;
mic.angleM1_Y = 0.0f;
mic.nGaz = 1.0f;

BIN
michelson

Binary file not shown.

View File

@ -8,13 +8,15 @@ out vec4 finalColor;
uniform vec2 center;
uniform float screenHeight;
uniform vec2 resolution;
//uniform vec2 resolution;
uniform float d1;
uniform float d2;
uniform float lambda;
//uniform float lambda;
uniform float angleM1;
uniform float angleM1_Y;
uniform float zoom;
uniform float lambdas[10];
uniform int lambdasCount;
const float PI = 3.14159265359;
@ -45,26 +47,43 @@ void main() {
float relX = (pixelX - center.x) * zoom;
float relY = (pixelY - center.y) * zoom;
vec3 baseColorVec = WavelengthToRGB(lambda);
// r^2
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.065;
float ringFactorBase = radiusSq * 0.065;
// Diff de marche du au coin d'air
float wDelta = (relX * angleM1 + relY * angleM1_Y) * 200.0f;
float wDelta = (relX * angleM1 + relY * angleM1_Y) * 200.0;
float currDelta = deltaLnm - ringFactor + wDelta;
float currDeltaBase = deltaLnm + wDelta;
// Formule de Fresnel : I = I_0 * cos^2(phi)
float K = PI / lambda;
float phase = currDelta * K;
float intensity = cos(phase);
intensity = intensity * intensity;
float currDelta = deltaLnm - ringFactorBase + wDelta;
vec3 finalVec = baseColorVec * intensity;
vec3 accumColor = vec3(0.0);
finalColor = vec4(finalVec, 1.0);
for(int i = 0; i < 10; i++) {
if (i >= lambdasCount) break;
float l = lambdas[i];
vec3 baseColorVec = WavelengthToRGB(l);
float currDelta = currDeltaBase - ringFactorBase;
float K = PI / l;
float phase = currDelta * K;
float intensity = cos(phase);
intensity = intensity * intensity;
accumColor += baseColorVec * intensity;
}
// finalColor = vec4(accumColor, 1.0);
// float K = PI / lambda;
// float phase = currDelta * K;
// float intensity = cos(phase);
// intensity = intensity * intensity;
// vec3 finalVec = baseColorVec * intensity;
//finalColor = vec4(finalVec, 1.0);
finalColor = vec4(accumColor, 1.0);
}