Просмотр полной версии : Геометрическая оптика
Erikozer
09.06.2012, 15:11
Здравствуйте. Вот уже третий день мучаюсь с построением изображения в собирающей линзе.
Есть точка, "оптический стол" и сама линза.
Нужно построить изображение по следующим правилам(я взял первые 2 правила, ибо третье кажется каким-то нереализуемым):
1.Луч, проходящий через оптический центр линзы, не преломляется.
2.Луч, падающий на линзу параллельно главной оптической оси, при выходе из линзы проходит через её фокус
3.Луч, падающий под углом на линзу, при выходе из линзы проходит через точку, лежащую в фокальной плоскости линзы. Эта точка является пересечением вспомогательного луча, параллельного главному лучу и проходящего через оптический центр линзы и перпендикуляра поднятого(или опущенного) из фокуса к главной оптической оси.
Второе предложение в третьем правиле вообще не понял.
Так вот, я столкнулся с большим количеством вариантов решения этой задачи и выбрал два из них:
1.Линии слева от линзы строить через graphics.moveTo и graphics.lineTo, благо координаты почти все есть, а именно нам известны(смотрим рисунок):
Координаты точек S, A, C, B(он же фокус)
Углы SAC, ACB, CED прямые
Проблема в том, что я незнаю, где пересекутся линии, идущие через фокус и через центр линзы.
Однако, погуглив я понял, что можно расчитать прирост по х и y каждой точки, например, отрезка АВ и таким образом продолжить строить после пересечения с фокусом. Аналогично для центра линзы.
Но я опять неузнаю, где они пересекутся.
http://higgs.**********/38567218/image.png
2.Вторая идея мне пришла сегодня "во сне", после целого вечера поиска тригонометрических примеров на AS3.
А что если нарисовать две линии и сделать их мувиклипами. Они заменят линии AD и SD.
При нажатии на кнопку построения эти линии будут повернуты на необходимую величину(нужный градус можно вычислить, благодаря известным координатам).
Но тут опять загвоздка.
Через какую функцию узнать, что они пересеклись? hitTest? Но мне нужна точная координата, для помещения копии начальной точки туда.
И еще одна проблема: нужно, чтобы отрезок AD при любом повороте не выезжал на левую часть линзы. через что ограничить показ объекта в определенной области? Маски? Ниразу не работал с ними, подскажите какую функцию использовать.
Вопрос в том, какой способ проще и быстрее(ибо времени до сдачи диплома у меня мало).
Ах да, с AS работаю впервые.
Silicium
09.06.2012, 16:14
Использовать уравнение тонкой линзы. 1/f = 1/a + 1/b, если не ошибаюсь
f - фокусное расстояние, a - расстояние от объекта (источника) до линзы, b - расстояние от линзы до изображения. Я бы сначала точки нашел а потом через них провел линии.
Зная f и a из уравнения легко b находится.
∠CBD = 180 - ∠q
∠CDE = 360 - ∠CBD - ∠y
∠CDB = 180 - ∠CBD - ∠y
CB известна, углы известны, считаем треугольник CBD
Erikozer
09.06.2012, 17:52
Зная f и a из уравнения легко b находится.
Это понятно, а по y оси?
∠CBD = 180 - ∠q
∠CDE = 360 - ∠CBD - ∠y
CB известна, углы известны, считаем треугольник CBD
∠CDE = 360 - ∠CBD - ∠y
Почему тут 360? Сумма углов в треугольнике = 180 градусов, получается
∠CDE = 180 - 90 - ∠y => ∠CDE = 90 - ∠y
Треугольник CBD не рассматриваем.
Только не совсем понимаю, зачем нам углы.
360 забудьте, ага. Жара. И не ∠CDE а ∠CDB )))
Треугольник CBD не рассматриваем. Только не совсем понимаю, зачем нам углы.Ну дело Ваше. Я думал Вас интересует гипотенуза CD, по которой собственно решается весь прямоугольный треугольник CED.
Вам ведь катеты найти надо, а у Вас кроме углов ничего нет. Решаем треугольник CBD — получаем гипотенузу, и зная углы, находим катеты в CED — т.е. координаты точки D.
Erikozer
09.06.2012, 19:56
Ну дело Ваше. Я думал Вас интересует гипотенуза CD, по которой собственно решается весь прямоугольный треугольник CED.
Значит ∠CBD = 180 - ∠q
∠q = arctan (AC , BC)
А дальше? Находим CD через одну из формул площади треугольника?
S = 1/2*a*b*sin ∠альфа
В нашем случае получается:
S = 1/2*CB*CD*sin ∠y
И вот тут я застрял. Площадь же неизвестна.
Нашел еще одну формулу площади (http://www.fxyz.ru/формулы_по_геометрии/формулы_площади/площадь_треугольника_через_углы/):
S = a^2 * sin ∠beta * sin ∠gamma / 2* sin ∠alfa
В нашем случае
S =1/2* CB^2 * (sin ∠y * sin ∠CBD / 2* sin ∠CDB)
∠CDB = 180 - ∠y - ∠CBD
По этим формулам через площадь вычислим CD
CD = 2*S / CB * sin ∠y
Поидее так.
Значит мы сможем найти площадь CED.
Вроде понял, потом по этой же формуле через 3 синуса и сторону искать длину катетов.
Спасибо, попробую, отпишу.
Silicium
09.06.2012, 21:01
По у через Г - увеличение линзы, равное -f/a; тоесть если координата источник y, то y' = -y*f/a Все просто
Wolsh решение правильное, согласен, там все считается. Покажу еще пару решений попроще. В вашем решении чтобы аналитически выразить (синусы/косинусы через начальные координаты считаются) результат через исходные координаты нужно тригонометрию помнить. Там у CDB синусы/косинусы не очень красивые будут.
Первое решение. Пишем уравнения через "проекции". CD=ED/sin(y), BD=ED/sin(q). CB=CD*cos(y) - DB*cos(q). В последнее равенство подставляются выражения для CD и BD, значения ctx(y), ctx(q) через начальные координаты и получается результат.
Второе решение. Навеяно первым, но не требует тригонометрии вообще. Треугольники SAC и CED подобны. Треугольники ACB и DEB подобны. CE/ED=SA/AC, BE/ED=BC/AC (из подобия). BC=CE-BE=(SA-BC)*ED/AC. Ну и ED=BC*AC/(SA-BC). Правда, в отличие от решения через "проекции" (предыдущий случай) здесь стоит построить несколько (три) различных случая для различных расположений точки D.
Silicium
10.06.2012, 12:22
Да вы издеваетесь! 1/f = 1/a + 1/b - вот это и есть ОБЩЕЕ решение. Зачем решать решенную задачу?
Erikozer
10.06.2012, 23:40
Пробую пока через формулу 1/f = 1/a + 1/b
Вроде так получается, но проблема с координатами, точнее откуда должно считать.
Silicium
11.06.2012, 00:00
f - фокусное расстояние. у Вас это CF. a - расстояние от объекта до линзы, соответственно SA. b - искомое расстояние до полученного изображение, соответственно CE. (Обычно вместо C пишут 0).
По вертикали:
если координата источник y, то y' = -y*f/a
Erikozer
11.06.2012, 14:04
Никак не получается, перепробовал все варианты, линии ведут себя неадекватно и не идут строго через фокус/центр линзы.
Вот что выходит, если делать через y' = -y*f/a. Слева с минусом, справа без.
Без минуса получается более менее, но линии все равно преломляются при выходе из центра или фокуса.
http://plasmon.**********/38600330/image.png
Ну и код:
Центр линзы (275,173)
Фокус справа (348,173)
buildbutton.addEventListener(MouseEvent.CLICK, Draw );
var v:Number;
var u:Number;
var k:Number;
var f:Number = 73; // расстояние от линзы до фокуса
var yf:Number;
var ydtop:Number;
function Draw( e:MouseEvent ):void
{
buildlines.graphics.clear();
buildlines.graphics.lineStyle(2, 0xff0000, .75);
initposx = ourobject.x;
initposy = ourobject.y;
u = 275-initposx; // расстояние от объекта до линзы
v = (f*u)/(u-f); // расстояние от линзы до изображения
k = v/u;
ydtop = initposy-((sizeSlider.value-10)/2);
yf = (ydtop*f/u);
trace(u,v,k,initposy);
// 1/f=1/a+1/b
//Строим от верхней точки объекта параллельную линию и через фокус
buildlines.graphics.moveTo(initposx, ydtop);
buildlines.graphics.lineTo(275,ydtop);
buildlines.graphics.lineTo(348,173);
buildlines.graphics.lineTo(275+v,yf+173);
//Строим от верхней точки объекта линию через центр
buildlines.graphics.moveTo(initposx, ydtop);
buildlines.graphics.lineTo(275,173);
buildlines.graphics.lineTo(275+v,yf+173);
Прибавляем 173 к yf, потому что началом координат будет считаться центр линзы.
Silicium
11.06.2012, 16:53
я писал на память - где-то мог и ошибиться (особенно не отвечаю за знаки). Но гугл (https://www.google.ru/search?hl=ru&gs_nf=1&cp=11&gs_id=d&xhr=t&q=%D1%82%D0%BE%D0%BD%D0%BA%D0%B8%D0%B5+%D0%BB%D0%B8%D0%BD%D0%B7%D1%8B&pf=p&sclient=psy-ab&oq=njyrbt+kbyp&aq=0l&aqi=g-l4&gs_l=&pbx=1&bav=on.2,or.r_gc.r_pw.r_cp.r_qf.,cf.osb&ion=1&biw=1517&bih=714) на что? Я просто подсказал, кдуа копать.
Тем более, на рисунках очевидна ошибка! На первом расстояние между изображением и ГОО меньше расстояния от источника до ГОО, а на втором рисунке нет, хотя источник одинаково удален от лизны. Следовательно смена знака тут влечет еще и изменене модуля? Вам не кажется, что так не должно быть? ABS(-173.568) == ABS(173.568);
Erikozer
11.06.2012, 17:15
Ладно, забил пока на подсчеты, делаю через поворот. За 2 часа сделал то, над чем бился 2 дня.
Думаю с выездом на панель настроек разберусь, но через что побыстрее ограничить линии, чтобы они не выползали за объект слева, если точки пересекаются справа от линзы и аналогично для пересечения слева?
Я правильно понимаю, что нужно сделать маску, в которой не будут видны определенные объекты и размещаться она должна в координатах нашей точки?
Точку пересечения буду искать через уравнения двух прямых, намного проще.
http://tau.**********/38603010/image.png
как то так. применять на контйенер, в котором вы рисуете линии
var mask_sprite:Sprite = new Sprite();
mask_sprite.graphics.beginFill(0x00ff00, 1);
mask_sprite.graphics.drawRect(0, 0, your_width, your_height);
mask_sprite.graphics.endFill();
your_movieClip.addChild(mask_sprite);
your_movieClip.mask = mask_sprite;
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.