Помощь - Поиск - Пользователи - Календарь
Полная версия: Высоты треугольника
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Глюк
Здравствуйте. Здесь часть программки,которая рисует треугольник и его высоты. Проблема в одном: там строчка выделена. Почему,когда g1=l она не переходит к выполнению условия??? Все пробую....скажите,где ошибка???Заранее благадарю!
Код
procedure TForm1.Button3Click(Sender: TObject);
const picScale = 10;
var
ma_x, ma_y, mb_x, mb_y, mc_x, mc_y: integer;
ha_x, ha_y, hb_x, hb_y, hc_x, hc_y: integer;
ba_x, ba_y, bb_x, bb_y, bc_x, bc_y: integer;
i,j,m:integer;
          k1,k2,k3,z1,z2,z3:integer;   {integer}
          p,a,b,c:real;
          g1,g2,l:{extended}real;
          Xh, Yh, Zh: integer;

begin
  with paintbox1.Canvas do begin
    pen.Color := clBlack;
    moveto(picScale*strtoint(edit1.Text), picScale*strtoint(edit2.Text));
    lineto(picScale*strtoint(edit3.Text), picScale*strtoint(edit4.Text));
    lineto(picScale*strtoint(edit5.Text), picScale*strtoint(edit6.Text));
    lineto(picScale*strtoint(edit1.Text), picScale*strtoint(edit2.Text));
pen.Color := clGreen;
    k1:=10*strtoint(edit1.Text);
   k2:=10*strtoint(edit3.text);
    k3:=10*strtoint(edit5.text);
  z1:=10*strtoint(edit2.text);
   z2:=10*strtoint(edit4.text);
    z3:=10*strtoint(edit6.text);
  a:= sqrt(sqr(k1-k2)+sqr(z1-z2));
  b:= sqrt(sqr(k2-k3)+sqr(z2-z3));
  c:= sqrt(sqr(k1-k3)+sqr(z1-z3));
  p:=(a+b+c)/2;


{g1:= abs(sqrt(sqr(i-k2)+sqr(j-z2))); }
  g2:= (2*sqrt(p*(p-a)*(p-b)*(p-c)))/c;
  l:=abs(g2);
    for i:=k1 to k3 do
    begin
    for j:=z1 to z3 do
    begin
     g1:= sqrt(sqr(i-k2)+sqr(j-z2));
      if (g1=l) then   {почему,когда g1=l она не переходит к выполнению условия???}
       begin
        Xh := i;
        Yh := j;  
       end;
       end; end;
       moveto(10*strtoint(edit3.Text), picScale*strtoint(edit4.Text));
    lineto(Xh, Yh);
volvo
Потому, что нельзя сравнивать вещественные числа напрямую... Сравнивай с погрешностью:

If abs(g1 - L) < 0.001 Then ...
Глюк
Спасибо,сейчас работает,но он не правильно высоту рисует...Почему не пойму,ведь правильные же условия?Опять где-то ошибочка,што ли?
Глюк
Цитата(volvo @ 22.04.2007 21:08) *

Потому, что нельзя сравнивать вещественные числа напрямую... Сравнивай с погрешностью:

If abs(g1 - L) < 0.001 Then ...



unsure.gif
может что-то не так в самом тексте? Он иногда правильно высоту рисует,а иногда - нет...Он что-то не учитывает?
Lapp
Цитата(Глюк @ 22.04.2007 23:30) *
может что-то не так в самом тексте? Он иногда правильно высоту рисует,а иногда - нет...Он что-то не учитывает?
Глюк, я попытался разобраться с твоим текстом, и кажется, мне это удалось..
Ты выбрал крайне странный способ рисования. Ты считаешь высоту как удвоенную площадь (по формуле Герона) делить на сторону. А дальше ты делаешь очень странную вещь.. Ты проходишь циклом по прямоугольнику, натянотому на сторону, и берешь в нем последнюю точку, где выполняется (приблизительное) равенство h=l , где l - это расстояние от вершины до сканируемой точки прямоугольника. Метод - хоть сейчас в кунсткамеру.. smile.gif Типа - машина железная, пусть считает - так, что ли?

Во-первых, этот метод сам по себе неверный (в этом множестве есть нужная точка, но она не последняя).
Во-вторых, подумай, что будет, если, например, k1>k3 (то есть точка А лежит правее С) ?
Или, скажем, если высота проходит вне треугольника?

Мой совет: рассчитай точку основания высоты по-человечески и не городи огород в чистом поле.. Не нужны тут циклы - ни двойные, ни одинарные.. smile.gif

PS
на будущее, когда задаешь такой вопрос, объясняй в общих чертах свой алгоритм. Продраться через твой причудливый код было непросто. Если ты изложишь алгоритм (как я сделал), то вероятность, скорость и правильность ответа тебе значительно повысятся.
Глюк
Цитата(Lapp @ 23.04.2007 8:34) *



Во-первых, этот метод сам по себе неверный (в этом множестве есть нужная точка, но она не последняя).
Во-вторых, подумай, что будет, если, например, k1>k3 (то есть точка А лежит правее С) ?
Или, скажем, если высота проходит вне треугольника?

Мой совет: рассчитай точку основания высоты по-человечески и не городи огород в чистом поле.. Не нужны тут циклы - ни двойные, ни одинарные.. smile.gif




а каким тогда способом можно найти точку,куда будет опущена высота?Я много чего просмотрел, ничего нормального не нашел?Может подскажете?
Lapp
Цитата(Глюк @ 23.04.2007 10:14) *

а каким тогда способом можно найти точку,куда будет опущена высота?Я много чего просмотрел, ничего нормального не нашел

Ну, например, так:
Высота из угла А делит противоположную сторону (a) на две части: а1 (при С) и а2 (при В).
По теореме Пифагора имеем:
a1^2 + h^2 = b^2
Отсюда находим а1.
После этого остается некоторая неопределенность, в какую сторону от С откладывать этот кусок. Для проверки этого можно посчитать а2 (аналогично). Дальше нужно сделать примерно следующее..
Если a1+a2 = a - откладываем внутрь треугольника.
Если a1+a2 > a , то
- если a1>a2 , то внутрь;
- в противном случае - наружу.
Проверь логику, я не совсем уверен..

Добавлено через 12 мин.
Вот, нарисовал картинки.. smile.gif Нажмите для просмотра прикрепленного файла
Глюк
Цитата(Lapp @ 23.04.2007 9:43) *

Ну, например, так:
Высота из угла А делит противоположную сторону (a) на две части: а1 (при С) и а2 (при В).
По теореме Пифагора имеем:
a1^2 + h^2 = b^2
Отсюда находим а1.
После этого остается некоторая неопределенность, в какую сторону от С откладывать этот кусок. Для проверки этого можно посчитать а2 (аналогично). Дальше нужно сделать примерно следующее..
Если a1+a2 = a - откладываем внутрь треугольника.
Если a1+a2 > a , то
- если a1>a2 , то внутрь;
- в противном случае - наружу.
Проверь логику, я не совсем уверен..



спасибо.Но, а как можно отложить отрезок,зная только его длину и незная его координат? unsure.gif
опять-таки меня тянет на цикл и поиск координат наабу?Но вы говорите,что их не рекомендовано использовать в этом случае?Других предположений у меня нет... unsure.gif
Глюк
unsure.gif unsure.gif
подскажите,пожалуйста
Lapp
Цитата(Глюк @ 23.04.2007 19:46) *

как можно отложить отрезок,зная только его длину и незная его координат?

Рисуй на листе бумаги параллельно с моими пояснениями.
У нас есть система координат - оси Х и У.
Далее, у тебя есть две точки: B (Bx,By) и C (Cx,Cy)

Делаем два преобразования системы координат:
1. Параллельный перенос (красные стрелки), такой, что т.В переходит в В', совпадающую с началом координат.
2. Поворот (зеленая стрелка) на минус угол, который составляет ВС с осью Х (назовем этот угол Т, от слова Тета, поворот производим на минус Т). После этого В"С" лежит вдоль оси Х.
Откладываем по оси Х нужную длину (от В", то есть от нуля). Внутрь треугольника - с плюсом, наружу - с минусом. Получаем точку О" с координатами (а1,0) - то есть по Х откладываем длину, по У не смещаемся.

Теперь выполняем те же самые преобразования в обратном порядке (все синими стрелками).
1. Поворот на плюс Т.
2. Параллельный перенос обратно.

Во время двух последних преобразований точка О" переходит сначала в О', потом в О.

Нажмите для просмотра прикрепленного файла

Результирующщие формулы записываются так (применяем матрицу поворота):

Ox = a1*cos(T) - 0*sin(T) + Вx
Oy = a1*sin(T) - 0*cos(T) + Вy

Средние слагаемые равны нулю. Остальные дадут нам координаты основания высоты.
Теперь осталось узнать угол Т. Его можно узнать из наклона прямой ВС. Например, так:

Т = ArcSin((Cy-By)/a)

Все понятно?
Глюк
Цитата(Lapp @ 24.04.2007 1:26) *

Все понятно?



вообще-то не все... unsure.gif


BC=a -это отрезок,на котором лежит высота треугольника,да...Вот,...и когда находим угол Т, arcsin получается больше 1?
И как тогда?
Lapp
Цитата(Глюк @ 24.04.2007 20:29) *

BC=a -это отрезок,на котором лежит высота треугольника,да...Вот,...и когда находим угол Т, arcsin получается больше 1?
И как тогда?

Этого не может случиться.

Т = ArcSin((Cy-By)/a)

Длина ВС равна а. А Сy-By - это проекция его длины на ось Y. Проекция всегда меньше длины самого отрезка.
Глюк
Цитата(Lapp @ 24.04.2007 20:58) *

Проекция всегда меньше длины самого отрезка.


yes2.gif

Упс...
вот я ступил: длину проекции измерил по клеткам,а длину отрезка ВС по линейки...Кошмар,что со мной твориться...
Глюк
у меня все-равно не так рисует...высота короткая получается и она смещена.

И каким образом лучше задавать координаты 2-ой точки отрезка,на которой лежит высота?


procedure TForm1.Button3Click(Sender: TObject);
const picScale = 10;
var
ma_x, ma_y, mb_x, mb_y, mc_x, mc_y: integer;
ha_x, ha_y, hb_x, hb_y, hc_x, hc_y: integer;
ba_x, ba_y, bb_x, bb_y, bc_x, bc_y: integer;
i,j,m:integer;
k1,k2,k3,z1,z2,z3,w1,w2:integer; {integer}
p,a,b,c,T,w_k1z1:real;
hc,ha,hb,l:{extended}real;
Xh, Yh, Zh: integer;

a1,a2:real;

begin
with paintbox1.Canvas do begin
pen.Color := clBlack;
moveto(picScale*strtoint(edit1.Text), picScale*strtoint(edit2.Text));
lineto(picScale*strtoint(edit3.Text), picScale*strtoint(edit4.Text));
lineto(picScale*strtoint(edit5.Text), picScale*strtoint(edit6.Text));
lineto(picScale*strtoint(edit1.Text), picScale*strtoint(edit2.Text));
pen.Color := clGreen;
k1:=10*strtoint(edit1.Text);
k2:=10*strtoint(edit3.text);
k3:=10*strtoint(edit5.text);
z1:=10*strtoint(edit2.text);
z2:=10*strtoint(edit4.text);
z3:=10*strtoint(edit6.text);
w1:=10*strtoint(edit8.Text);
w2:=10*strtoint(edit9.Text);

b:= sqrt(sqr(k1-k2)+sqr(z1-z2));
c:= sqrt(sqr(k2-k3)+sqr(z2-z3));
a:= sqrt(sqr(k1-k3)+sqr(z1-z3));
p:=(a+b+c)/2;

w_k1z1:= sqrt(sqr(k1-w1)+sqr(z1-w2));

hc:= (2*sqrt(p*(p-a)*(p-b)*(p-c)))/c;
ha:= (2*sqrt(p*(p-a)*(p-b)*(p-c)))/a;
hb:= (2*sqrt(p*(p-a)*(p-b)*(p-c)))/b;


T:=arcsin((w2-z2)/w_k1z1);

a1:=sqrt(sqr(b)-sqr(ha));
a2:=sqrt(sqr©-sqr(ha));
if a1+a2=a then
begin
Xh := round(hc*cos(T))+k1;
Yh := round(hc*sin(T))+z1;
end;
if a1+a2>a then
begin
if a1>a2 then
begin
Xh := round(hc*cos(T))+k1;
Yh := round(hc*sin(T))+z1;
end
else
begin
Xh := round(-hc*cos(T))+k1;
Yh := round(-hc*sin(T))+z1;
end;
end;
moveto(picScale*strtoint(edit1.Text), picScale*strtoint(edit2.Text));
lineto(Xh, Yh);
end;
end;

Lapp
Цитата(Глюк @ 25.04.2007 1:20) *

у меня все-равно не так рисует...высота короткая получается и она смещена.
И каким образом лучше задавать координаты 2-ой точки отрезка,на которой лежит высота?
Ну, давай исправлять..
О некотором мне не удалось догадаться (не понимаю, почему бы не сказать самому, что есть что?) - что такое w1 и w2?
w_k1z1:= sqrt(sqr(k1-w1)+sqr(z1-w2));

Сответствеено, я не понимаю, как ты вычисляешь Т:
T:=arcsin((w2-z2)/w_k1z1);

Правда, я сам немного ошибся в расчете Т (точнее, сделал расчет не до конца - только для углов меньше Пи/2 по модулю). Вот полная версия:
  T:=arcsin((Cy-By)/a);
if Bx>Cx then T:=Pi-T;

Идем дальше.. а1 и а2 ты преепутал местами. Должно быть так:
  a1:=sqrt(sqr(c )-sqr(ha));
a2:=sqrt(sq(b)-sqr(ha));

А дальше логику можно сильно упростить:
  if (a1+a2-a>1e-5)and(a1<a2) then a1:=-a1;

И дальше все делать по общим формулам (пишу свои, потому что у тебя вообще полный бардак; сравни - увидишь)
  Mx := round(a1*cos(T))+Bx;
My := round(a1*sin(T))+By;
moveto(Ax,Ay);
LineTo(Mx,My);

Здесь точка М (Mx,My) - это вместо точки О на рисунке. Что такое Ах и т.п. - надеюсь, разберешься.. Я твоих k1 и z3 не понимаю.. Это надо же себя так путать самого..
Вот, приблизительно так.
Давай, делай и говори, что получается..
Глюк
Lapp
Ура. smile.gif Всё наконец получилось! Спасибо большое за помощь!
Я просто сам запутался с этими обозначениями!
Глюк
Ещё я этот же способ применил и для рисования биссектрис-ВСЁ получается!!! good.gif
Спасиб ещё раз!
Lapp
Цитата(Глюк @ 25.04.2007 21:29) *

Ещё я этот же способ применил и для рисования биссектрис-ВСЁ получается!!! good.gif

Приятно слышать! smile.gif Просто бальзам по сердцу.. Поздравляю!
Не знаю, нужно ли тебе, но у меня совет по дальнейшему улучшению и развитию.. Я бы сделал что-то типа такого..
Делаешь примерно такую структуру:

type
tPoint=record {тип точка}
x,y {координаты}
end;
tTriangle=record {тип треугольник}
Body:array[1..3]of record {тело}
Top,Hight,Bis,Med:tPoint; {вершины!! и основания высот, биссектрис, медиан}
l:real {длина стороны}
end;
s,p: {площадь, периметр}
end;

var
A,B: tTriangle;

Для задания треугольника необходимы только поля вершин.
После этого все вычисления проводишь в цикле по вершинам и т.п. Вывод графики тоже в цикле.. smile.gif
Успехов!
Глюк
Lapp

Ок. Спасибо! Попробуем smile.gif
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.