Добрый день... У меня возникла маленькая неприятность, оказывется я не знаю как провести линию через две точки на весь экран. Т.е. я знаю как соеденить две точки линией и т д... Ну вот чтобы провести линию через эти две точки на весь экран я не знаю как это сделать. Может есть какая-то легкая процедура и т.д.?
К примеру: есть А(100,100) и B(200,200) - нужно провести через них линию
И еще, я так увлекся "украшательством" своей программы, что забыл про свое условие, короче у меня оврал, помогите: Есть уравнение прямой, есть две точки, прямая разбивает плоскость на подплоскости, нужно опеределать лежат ли эти две точки в разных. Уранение прямой разное, в общем виде: sx+ty+u=0 и точки (a,b) и (c,d). Т.е. a,b,c,d,s,t,u вводятся с клавиатуры.
Я прикрепил свой исходник.... Он еще не полность доделал... Немного о нем расскажу, чтобы было понятно: точки А,Б - обычные точки (вводите их около плюс-минус 10) точки X1 и X2 - точки из прямой, т.е. это две точки принадлежащие этой прямой. "Новые данные" - это идет "переработка" под вывод этих точек на координатной плоскости, например точка А(-2;1) - это А(280;220) - ну если учесть, что у меня точка (320;240) это центр, а одна "еденица" - это 20 пикселей.
Вообщем я должен построить прямую на весь экран, которая проходит через точки X1 и X2 и потом опередалеть лежит ли точки А и Б в одной подплоскости.
P.S. Если я что-то непонятно написал, вы спрашивайте...
Прикрепленные файлы
GRAFIK.PAS ( 1.69 килобайт )
Кол-во скачиваний: 249
может, будет полезно
типы данных:
type
TPoint=record
x,y:integer;
end;
TLine=record
A,B,C:real; {Ax+By+C=0}
end;
procedure InitLine(var L: TLine; pA,pB: TPoint);
begin
L.A:=pB.y-pA.y;
L.B:=pA.x-pB.x;
L.C:=pA.y*(pB.x-pA.x)-pA.x*(pB.y-pA.y);
end;
function SignPoint(L:TLine;P:TPoint):integer;
var r:real;
begin
r:=L.A*P.x+L.B*P.y+L.C;
if abs®<=0.001 then
SignPoint:=0
else
if r<0 then
SignPoint:=-1
else
SignPoint:=1;
end;
Если тебе не обязательно делать всё по-честному, можешь существенно выйти за пределы экрана.
Чтобы провести прямую, соединяющую точки Х1 и Х2, продли отрезок Х1-Х2 тысячекратно в обе стороны:
X1 + (X1-X2) * 1000 -> X2 + (X2-X1) * 1000
Понятно, что экран полностью пересечется.
Что касается вопроса про точки А и Б - нужно проверить, что ориентированные площади треугольников Х1Х2А и Х1Х2Б имеют одинаковый знак:
def OrientS(a, b, c) = (a.x-c.x)*(b.y-c.y) - (a.y-c.y)*(b.x-c.y)
return sign(OrientS(Х1, Х2, А)) = sign(OrientS(Х1, Х2, Б))
Спасибо, что ответили, кое что прояснилось... Правда я не все понял
мисс_граффит это сильно сложно для меня, не мой уровень так сказать...
Michael_Rybak прочитал про ориантированную площадь треугольника, поискал в Инете, нашел такую формулу (твоя мне показалась сложной):
Ориентированная площадь S треугольника с вершинами P1, P2, P3:
. . . . | x1 y1 1 |
S = 1/2 | x2 y2 1 | = 1/2*[x1(y2-y3)+x2(y3-y1)+x3(y1-y2)]
. . . . | x3 y3 1 |
(точки поствил, что бы не смещалось)
У меня допустим точки P1, P2 - это точки X1 и X2, а в P3 я подставляю точку А и потом точку B. Попробовал, вроде все работает, если точки в разных подплоскоятх, то площади отличаются знаком.
Но вот насчет "продления" я не понял как это сделать.... Меня впринципе не интересует, где будут концы этого отрезка, главное чтобы он пересек экран (для наглядности). Можешь написать формулу продления отрезка более доходчиво для меня.
DIMMUA, ты выбрал не очень удачные названия точек, Х1 и Х2.. Можно я буду называть их M и N?
Так вот, предложение Michael_Rybak'а заключается в следующем..
Точки как бы представлены векторами, проведенными к ним из начала координат, назовем эти вектора так же, M и N. Тогда разность этих векторов представит сам отрезок:
а=M-N - вектор от точки N к точке M.
b=N-M - наоборот.
Рыбак предлагает умножить этот отрезок на 1000 и отложить, что получится, в обе стороны (продлить).
Тогда мы получим новые две точки, назовем их K и L :
K = M + а*1000
L = N + b*1000
Если расписать это все в координатах, получим:
Kx = Mx + (Mx-Nx)*1000
Ky = My + (My-Ny)*1000
Lx = Nx + (Nx-Mx)*1000
Ly = Ny + (Ny-My)*1000
Вот эти точки и соединяй оператором Line.
Теперь понятнее?
P.S.
DIMMUA, спасибо тебе за нормальную подробную постановку задачи с объяснениями и вежливый человеческий тон. Душа отдыхает в такой теме.. Просто хочется отвечать!
Добавлено через 4 мин.
Хочу добавить, что мне метод Рыбака не очень по душе.. Так можно запросто вылететь за пределы диапазона целых чисел. Я бы предложил все же находить точное пересечение линии с границей экрана..
Lapp Спасибо! Все понял, даже получилось, скоро все доделаю, может еще что-то "красивее" сделаю и выложу исходник, может кому-то понадобится.
Щас правда как-то примитивно постараюсь ограничить, чтобы моя прамая не сильно вылазила за пределы экрана, а то и впраду за ошибку выдаст в самый неподходящий момент.
Программа получилась, все работает... В данный момент занимаюсь украшательством. Хотел сказать, что мне для выполнения этой задачи графика не нужна была, мы её в универе еще не изучали, поэтому у меня было столько вопросов. Кстати, а как вывести значение переменной на экран в графическом режиме? Например:
А(а;b) - и вот я пишу OutTextXY(10,10, ' A(',a,';',b,')'); - т.е. по типу как "writeln" - а оно выдает ошибку, я так понимаю этой функцией можно только текст вывести?
А какже тогда вывести значение какой-то переменной? Пробовал writeln - вообще не видно, что оно выводит, т.е. вроде как вывело, но ничего не видно. Пробовал менять цвет текста - ничего, правда в текстовом режиме цвет изменился.
P.S. Моя программа, наслаждайтесь... Знаю, для многих она покажется легкой, но для меня
Фичи программы:
1. Проверка пароля... и заметте вы не видите сам пароль при вводе. (пароль 1234567890)
2. Сделал ограничение, чтобы моя прямая не сильно вылазила за пределы экрана... т.е. я "умножаю" отрезок до тех пор, пока все вершины не скроются с экрана... Т.е. таким способом я врятли выйду за пределы integer.
3. В конце выводит время выполнения кода (кстати, взято с вашего сайта )
Прикрепленные файлы
LAB16.PAS ( 4.91 килобайт )
Кол-во скачиваний: 273
Для вывода используй TextOut или OutText, уже не помню, как в Паскале.
Что касается выхода за диапазон - можно не умножать на 1000, а умножать на 2 до тех пор, пока за экран не выйдем. Так точно останемся в Integer.