IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> Высоты треугольника
сообщение
Сообщение #1


Новичок
*

Группа: Пользователи
Сообщений: 34
Пол: Мужской

Репутация: -  0  +


Здравствуйте. Здесь часть программки,которая рисует треугольник и его высоты. Проблема в одном: там строчка выделена. Почему,когда 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);


Сообщение отредактировано: Глюк -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






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

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


Сообщение отредактировано: volvo -
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Новичок
*

Группа: Пользователи
Сообщений: 34
Пол: Мужской

Репутация: -  0  +


Спасибо,сейчас работает,но он не правильно высоту рисует...Почему не пойму,ведь правильные же условия?Опять где-то ошибочка,што ли?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Новичок
*

Группа: Пользователи
Сообщений: 34
Пол: Мужской

Репутация: -  0  +


Цитата(volvo @ 22.04.2007 21:08) *

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

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



unsure.gif
может что-то не так в самом тексте? Он иногда правильно высоту рисует,а иногда - нет...Он что-то не учитывает?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


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

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

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

PS
на будущее, когда задаешь такой вопрос, объясняй в общих чертах свой алгоритм. Продраться через твой причудливый код было непросто. Если ты изложишь алгоритм (как я сделал), то вероятность, скорость и правильность ответа тебе значительно повысятся.


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Новичок
*

Группа: Пользователи
Сообщений: 34
Пол: Мужской

Репутация: -  0  +


Цитата(Lapp @ 23.04.2007 8:34) *



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

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




а каким тогда способом можно найти точку,куда будет опущена высота?Я много чего просмотрел, ничего нормального не нашел?Может подскажете?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(Глюк @ 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 Прикрепленное изображение


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Новичок
*

Группа: Пользователи
Сообщений: 34
Пол: Мужской

Репутация: -  0  +


Цитата(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
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Новичок
*

Группа: Пользователи
Сообщений: 34
Пол: Мужской

Репутация: -  0  +


unsure.gif unsure.gif
подскажите,пожалуйста
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(Глюк @ 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)

Все понятно?


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Новичок
*

Группа: Пользователи
Сообщений: 34
Пол: Мужской

Репутация: -  0  +


Цитата(Lapp @ 24.04.2007 1:26) *

Все понятно?



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


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

Сообщение отредактировано: Глюк -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(Глюк @ 24.04.2007 20:29) *

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

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

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

Длина ВС равна а. А Сy-By - это проекция его длины на ось Y. Проекция всегда меньше длины самого отрезка.


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Новичок
*

Группа: Пользователи
Сообщений: 34
Пол: Мужской

Репутация: -  0  +


Цитата(Lapp @ 24.04.2007 20:58) *

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


yes2.gif

Упс...
вот я ступил: длину проекции измерил по клеткам,а длину отрезка ВС по линейки...Кошмар,что со мной твориться...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Новичок
*

Группа: Пользователи
Сообщений: 34
Пол: Мужской

Репутация: -  0  +


у меня все-равно не так рисует...высота короткая получается и она смещена.

И каким образом лучше задавать координаты 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;

 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(Глюк @ 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 не понимаю.. Это надо же себя так путать самого..
Вот, приблизительно так.
Давай, делай и говори, что получается..


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Новичок
*

Группа: Пользователи
Сообщений: 34
Пол: Мужской

Репутация: -  0  +


Lapp
Ура. smile.gif Всё наконец получилось! Спасибо большое за помощь!
Я просто сам запутался с этими обозначениями!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Новичок
*

Группа: Пользователи
Сообщений: 34
Пол: Мужской

Репутация: -  0  +


Ещё я этот же способ применил и для рисования биссектрис-ВСЁ получается!!! good.gif
Спасиб ещё раз!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(Глюк @ 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
Успехов!


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #19


Новичок
*

Группа: Пользователи
Сообщений: 34
Пол: Мужской

Репутация: -  0  +


Lapp

Ок. Спасибо! Попробуем smile.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 29.03.2024 17:14
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name