Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.05.2012, 18:35   #1
OPEJI
Пользователь
 
Регистрация: 01.04.2011
Сообщений: 13
По умолчанию Дисперсия на призме

Добрый день уважаемые участники форума.
Пытаюсь написать программу на делфи чтобы была хоть чуток видна дисперсия.
Хочу сделать по простому из одной точки пустить по очереди 7 лучей разных цветов, и чтобы на выходе из призмы получилось что-то типо радуги.
Примерно вот так:

Проблема у меня состоит в том, что я никак не могу понять как вычисляется коэффициент преломления от длины волны.
Нашел формулу:
Цитата:

L — длина волны в вакууме;
a, b, c, … — постоянные, значения которых для каждого вещества должны быть определены в опыте. В большинстве случаев можно ограничиться двумя первыми членами формулы Коши.
но не знаю что за такие постоянные a, b, c...
OPEJI вне форума Ответить с цитированием
Старый 25.05.2012, 23:16   #2
ViktorR
Старожил
 
Регистрация: 23.10.2010
Сообщений: 2,309
По умолчанию

Думаю, что можно так:
Найти таблицу зависимости показателя преломления от длинны волны, например тут: http://www.dpva.info/Guide/GuidePhys...eOfwaveLength/
Затем, выбрав степень приближения, составить и решить систему уравнений, для нахождения коэффициентов a, b, c, ...
Материал и угол призмы так же должны быть определены.

Думаю, что так можно ...
Как-то так, ...
ViktorR вне форума Ответить с цитированием
Старый 26.05.2012, 23:02   #3
OPEJI
Пользователь
 
Регистрация: 01.04.2011
Сообщений: 13
По умолчанию

Коэффициенты A и B нашел:
A=1.504
B=4.568*10^3
Теперь если подставлять в эту формулу Коши

длины волн, то находятся нужные нам преломления, но теперь у меня другая проблема, как это нарисовать в делфи, делал по тупому для каждого из 7 лучей указывал своё преломление и свою процедуру рисования, но преподаватель сказал, а что если мы захотим сделать спектр из 200 лучей, то для каждого луча тоже будем высчитывать преломление?
У меня в мыслях было пару идей, но реализовать их что-то не получается...
Первая мысль - это масив, но с ними я не дружу.
Вторая мысль - цикл с переменной, за значения цикла взять длину волны скажем
Код:
for lambda:= 400 to 700 do
но тут у меня проблема в том, что я не могу привязать высчитанное значение преломления.
Вот код, который умеет рисовать линию через призму по закону преломления
Код:
type
  TForm1 = class(TForm)
    Button2: TButton;
    PaintBox1: TPaintBox;
    TrackBar1: TTrackBar;
    Button1: TButton;
    ygol: TLabeledEdit;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure TrackBar1Change(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
const
  c=300000000;
  d=0.1;
  dt=1E-11;
  maxN=3;

var
  Form1: TForm1;
  phi1, dphi1, r1, r2, x1, x2, y1, y2: extended;
  iter, i , j, y99: integer;


implementation

{$R *.dfm}

function fn1(x,y: extended): extended; //Эта функция создаёт границы призмы, учитывая что вне призмы коэффициент преломления 1, а в призме 1.5
 begin
   if (y>400)or(y<-300+1.71*x)or(y<600-1.71*x) then fn1:=1 else fn1:=1.5;
end;

procedure TForm1.Button2Click(Sender: TObject); //Эта процедура рисует призму из тех значений что выше
var cl: TColor; i, j: integer;
begin
for i:=0 to 545 do
for j:=0 to 529 do begin
cl:=round((fn1(i,j))*255);
paintbox1.Canvas.Pixels[i,j]:=RGB(cl,cl,cl);
button1.Enabled:=true;
end;
end;

procedure ShowLines; //Эта процедура рисует лучи через призму по закону преломлений
begin
  x2:=x1+d*Sin(phi1);
  y2:=y1-d*Cos(phi1);
  repeat
    R1:=c/fn1(x1,y1)*dt;
    R2:=c/fn1(x2,y2)*dt;
    dPhi1:=(R1-R2)/d;
    Phi1:=Phi1-dPhi1;
    x1:=x1+R1*Cos(Phi1);
    y1:=y1+R1*Sin(Phi1);
    x2:=x2+R2*Cos(Phi1);
    y2:=y2+R2*Sin(Phi1);
    Form1.paintbox1.Canvas.Pixels[Round(x1),Round(y1)]:=ClRed;
  until (x1>Form1.paintbox1.Width) or (y1>Form1.paintbox1.Height) or (x1<0) or (y1<0);
  end;

procedure TForm1.Button1Click(Sender: TObject); //Эта процедура запускает выполнение самой программы
var
k:extended;
 begin
 k:=strtofloatdef(ygol.text,0);
  x1:=1; //начальная координата x луча
  y1:=y99; //начальная координата y луча
  phi1:=k*pi/180; //начальный угол луча
  Showlines;
end;

procedure TForm1.TrackBar1Change(Sender: TObject);
begin
y99:= TrackBar1.Position; //начальная координата y луча
end;
Помогите пожалуйста привязать эту формулу Коши в данный код...

Последний раз редактировалось OPEJI; 26.05.2012 в 23:09.
OPEJI вне форума Ответить с цитированием
Старый 26.05.2012, 23:19   #4
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

Что-то не понял, где в Вашей программе задается коэффициент преломления.

И еще: на основе чего ShowLines что-то рисует?
Обычно все необходимые параметры передаются в процедуру через параметры. У Вас параметры отсутствуют, а глобальные переменные не описаны.
s-andriano вне форума Ответить с цитированием
Старый 26.05.2012, 23:30   #5
OPEJI
Пользователь
 
Регистрация: 01.04.2011
Сообщений: 13
По умолчанию

Цитата:
Сообщение от s-andriano Посмотреть сообщение
Что-то не понял, где в Вашей программе задается коэффициент преломления.

И еще: на основе чего ShowLines что-то рисует?
Обычно все необходимые параметры передаются в процедуру через параметры. У Вас параметры отсутствуют, а глобальные переменные не описаны.
Код:
function fn1(x,y: extended): extended; //Эта функция создаёт границы призмы, учитывая что вне призмы коэффициент преломления 1, а в призме 1.5
 begin
   if (y>400)or(y<-300+1.71*x)or(y<600-1.71*x) then fn1:=1 else fn1:=1.5;
end;
Вот эта функция как раз и задаёт коэффициент преломления вне призмы и в призме.
На основании этой функции рисуется сама призма процедурой(эта процедура просто визуальное оформление)
Код:
procedure TForm1.Button2Click(Sender: TObject); //Эта процедура рисует призму из тех значений что выше
var cl: TColor; i, j: integer;
begin
for i:=0 to 545 do
for j:=0 to 529 do begin
cl:=round((fn1(i,j))*255);
paintbox1.Canvas.Pixels[i,j]:=RGB(cl,cl,cl);
button1.Enabled:=true;
end;
end;
Далее ShowLine берет все значения констант и коэффициент преломления из функции fn1 и высчитывает координаты где нужно рисовать луч
OPEJI вне форума Ответить с цитированием
Старый 26.05.2012, 23:41   #6
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

А что за параметры у функции fn1?

И еще я спросил насчет ShowLines - что она рисует и на основе каких данных?
s-andriano вне форума Ответить с цитированием
Старый 27.05.2012, 00:02   #7
OPEJI
Пользователь
 
Регистрация: 01.04.2011
Сообщений: 13
По умолчанию

Цитата:
Сообщение от s-andriano Посмотреть сообщение
А что за параметры у функции fn1?
Код:
function fn1(x,y: extended): extended;
 begin
   if (y>400)or(y<-300+1.71*x)or(y<600-1.71*x) then fn1:=1 else fn1:=1.5;
end;
x y это координаты
(y>400)or(y<-300+1.71*x)or(y<600-1.71*x) вот этими условиями на координатной плоскости создается невидимая призма
fn1:=1 fn1:=1.5 это коэффициенты преломления, 1 это вне призмы, то есть "воздух", 1.5 это внутри призмы, то есть "стекло"

Цитата:
Сообщение от s-andriano Посмотреть сообщение
И еще я спросил насчет ShowLines - что она рисует и на основе каких данных?
Она рисует луч по вычисляемым координатам
Код:
procedure ShowLines;
begin
  x2:=x1+d*Sin(phi1); //Вычисление координат второго луча
  y2:=y1-d*Cos(phi1);
  repeat
    R1:=c/fn1(x1,y1)*dt; //Вычисление радиусов сферических волн
    R2:=c/fn1(x2,y2)*dt;
    dPhi1:=(R1-R2)/d; //Изменение угла распространения света
    Phi1:=Phi1-dPhi1; //Новый угол распространения света
    x1:=x1+R1*Cos(Phi1); //Новые координаты точек первого
    y1:=y1+R1*Sin(Phi1);
    x2:=x2+R2*Cos(Phi1); //и второго лучей
    y2:=y2+R2*Sin(Phi1);
    Form1.paintbox1.Canvas.Pixels[Round(x1),Round(y1)]:=ClRed; //Рисование только первого луча
  until (x1>Form1.paintbox1.Width) or (y1>Form1.paintbox1.Height) or (x1<0) or (y1<0); //Вычисления завершаются если луч вышел за пределы экрана
  end;
Сначало в первые формулы подставляются начальные кооринаты, откуда вылетает луч.
Далее в цикле:
Высчитываются радиусы сферических волн(с - скорость света в вакууме, fn1(x1,y1) - коэффициент преломления в данных точках, пока луч летит в "воздухе" он равен 1, когда луч влетает в призму он стает равным 1.5, вылетает из призмы и стает опять равным 1, dt-квант времени для точности модели
Далее вычисляются углы, пока мы летим в воздухе угол равен 0, как только луч сталкивается с призмой коэффициент преломления изменяется и угол луча соответственно изменяется
Далее вычисляются координаты движения луча, т.е. он высчитывает по какой траектории должен лететь луч...
OPEJI вне форума Ответить с цитированием
Старый 27.05.2012, 00:20   #8
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

Алгоритм вычисления так до конца и не понял. Но попытаюсь предложить, куда внести изменение коэффициента преломления.

Если не пытаться изменить стиль Вашей программы, то коэффициент преломления целесообразно хранить в глобальной переменной и в функции fn1 вместо константы 1.5 подставлять значение этой переменной.

Т.е. в TForm1.Button1Click задаете длину волны и по ней вычисляете коэффициент преломления. Если нужно - задаете разные значения длины волны в цикле.
Только правильно согласуйте величину B с размерностью длины волны. Потому как задана она явно не в СИ.
s-andriano вне форума Ответить с цитированием
Старый 27.05.2012, 00:21   #9
OPEJI
Пользователь
 
Регистрация: 01.04.2011
Сообщений: 13
По умолчанию

Спасибо, попробую...
OPEJI вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Дисперсия tema654 Microsoft Office Excel 3 15.12.2011 14:28
В прямой четырехугольной призме провести сечение, проходящее через сторону нижнего основания под углом 30 ramp1 Паскаль, Turbo Pascal, PascalABC.NET 0 04.06.2011 10:39
Дисперсия CesaR_JC Помощь студентам 15 23.05.2010 01:48
Дисперсия. Гистограмма p4serhiy Помощь студентам 2 15.04.2010 08:34
дисперсия массивов And_DaviD Общие вопросы C/C++ 3 16.02.2010 19:45