Добавлен , опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
Lua
Тип:
Алгоритм
часть 1
часть 2
как пишут многие, что это преподают в начальных курсах школы. но многое я пропустил. поэтому может пригодится. Тут даны теоретические задания с ответами, и нужно дать решения.
Решил выложить сюда, тк тут списки под катами находить легче. Чем крутить блокнот
Русско-английский словарик
при интерпретации кода с чужого языка на родной lua может пригодится. я например, часто встречаю ранее не понятые мной функции dot, cross, swap и пр. Нигде не указывают.
точка point
вектор vector
прямая line
луч ray
отрезок segment
угол angle
окружность circle
треугольник triangle
прямоугольник rectangle
квадрат square
многоугольник polygon
окружность circle
медиана median
биссектриса bissector
высота altitude
пересечение intersection
длина length
периметр perimeter
площадь area
касательная tangent
скалярное произведение dot product
векторное произведение cross product
вектор нормали normal vector
перестановка swap(a,b) => на lua аналогия a,b=b,a
Точность вычислений
Все действия с действительными числами выполняются приближенно. Поэтому два действительных числа никогда нельзя сравнивать на точное равенство. Мы будем считать два числа равными, если они отличаются не больше, чем на некоторое значение ε. Определение правильного ε  некоторое умение. Для справки: машинная точность вычислений (машинное эпсилон) равно 1.19209e-07 для действительных чисел одинарной точности и 2.22045e-16 для действительных чисел двойной точности.
Можно в луа так прописать:
EPS = 1E-9; <= число, записанное в экспоненциальном виде
1E-9; <= 9 знаков после запятой. 1e-9 - это 0.00000000001. Число знаков можно изменить.
Если вместо "-" поставить "+" => добавляет нули 1000000000000000000 - это 1e+18.
Итак, если есть два действительных числа x и y, то мы считаем, что
x = y, если |x − y| < ε, (равно)
x ≠ y, если |x − y| > ε, (не равно)
x < y, если x < y − ε, (меньше)
x ≤ y, если x < y + ε, (меньше или равно)
x > y, если x > y + ε, (больше)
x ≥ y, если x > y − ε (больше или равно)
пример
На jass знак равно "==" в варике округляет, а вот не равно - нет. У тебя и выводит 90.000, потому что R2S округляет до 3-го знака, а на самом деле там было что-то вроде 89.999999. 90 != 89.999999 в варике, потому условие прошло. Хочешь, чтобы не прошло, используй not (90 == angle). Тогда 89.999999 округлится до 90, и условие не пройдёт
Может это и на Lua работать неизвестно.
математические функции для lua
не все нужные функции есть в lua. Некоторые приходится самому допиливать
sign знак параметра
-- Получение знака параметра
-- Возвращает -1,0,1 (интересная механика, возвращает bool, но получаем на выходе int)
function math.sign(value)
    return value < 0 and -1 or value > 0 and 1 or 0
end
округление в большую/меньшую сторону
--округление в большую/меньшую сторону
--в большую: 0.5 => 1.0 or 0.3 => 0.0
--в меньшую: -0.5 => -1. or -0.3 => 0.0
function RoundEx(num)
  local inv = math.floor(math.abs(num) + 0.5)
    return num < 0 and inv * -1 or inv
end

function round(x, n)
    n = math.pow(10, n or 0)
    x = x * n
    if x >= 0 then x = math.floor(x + 0.5) else x = math.ceil(x - 0.5) end
    return x / n
end
перевод float в integer
по факту в lua есть функция math.tointeger. Но она не работает идеал, то ли это связано с версиями, то еще чего. Я не знаю.
можно разделить на 0.5//1 = 0 - отбрасывает. но тоже не всегда работает.
Есть функция math.modf(a)
пример x,y=math.modf(115.8) --x=115, y=0.8. По факту надо x=math.modf(115.8)
--конверт float в integer
--по факту отсекает/отбрасывает дробную часть
--а можно использовать math.tointeger(float)
function toint(n)
    local s = tostring(n)
    local i, j = s:find('%.')
    if i then
        return tonumber(s:sub(1, i-1))
    else
        return n
    end
end
gcd наибольший общий делитель (НОД)
пример: есть 3 числа: 2,-64,512. Среди них найти целый полож наибольший общий делитель, при делении которого получаются целые числа.
--наибольший общий делитель между a,b gcd>0
function gcd(a, b)
	return b==0 and a or gcd(b,a%b)
end
--наибольший общий делитель между a,b,c
function nod(a, b, c)
	return gcd(gcd(a,b),c)
end
print(gcd(54,24)) --Ответ: 6
print(nod(2,-64, 512)) --Ответ: 2
lcm наименьшее общее кратное (НОК)
-- Наибольший общий делитель НОД
-- реализация алгоритма Евклида
function gcd(a, b)
  if b == 0 then
    return a
  end
  return gcd(b, a % b)
end

-- Наименьшее общее кратное НОК
-- связь с НОД (вычисление через НОД)
function lcm(a, b)
  return math.abs(a * b) / gcd(a, b)
end

-- НОК для массива чисел
function lcm_array(arr)
  -- Если количество элементов в массиве меньше 2, то
  -- прои кол.ел. == 0 возвращается nil
  -- а при кол.ед == 1 возвращается первый элемент
  if #arr < 2 then
    return arr[1]
  end
  -- идея заключается в использовании свойства ассоциативности
  res = arr[1]
  for i = 2, #arr do
    res = lcm(res, arr[i])
  end
  return res
end

-- Тест 1
A = { }
print(lcm_array(A)) --Ответ: nil
-- Тест 2
A = { 5 }
print(lcm_array(A)) --Ответ: 5
-- Тест 3
A = { 2, 3 }
print(lcm_array(A)) --Ответ: 6
-- Тест 4
A = { 2, 3, 4 }
print(lcm_array(A)) --Ответ: 12
-- Тест 5
A = { 5, 4, 20, 2 } 
print(lcm_array(A)) --Ответ: 20
-- Тест 6
A = { 1, 1, 2, 3, 5, 8, 13, 21, 34 }
print(lcm_array(A)) --Ответ: 185640
конвертация строки ascii в dec
function ascii2decimal(str)
    str = string.reverse(str)
    local result = 0
    local pw = 1
    for i=1, #str do
        local c = str:sub(i,i)
        result = result + string.byte(c)*pw
        pw = pw*256
    end
    return result
end
среднее значение среди 3 чисел
довольно часто приходиться подбирать по условию типа a>b>c 3 числа
--найти середину между 3 числами
function math.mid(a,b,c,onlyMiddle)
	local Max = math.max(a,b,c)
	local Min = math.min(a,b,c)
	local Middle
	if Max > a and Min < a then
		Middle = a
	elseif Max > b and Min < b then
		Middle = b
	else
		Middle = c
	end
	if onlyMiddle then
		return Middle
	end
	return Max,Middle,Min
end
перевод радиан в градусы, и обратно
ссылка
Ну чтобы перевести, из градусов в радианы
180° = pi радиан = 3,14...
Если знаешь расположение градусов в окружности (там 2pi = 360°, или pi/2 = 90°)
60° = pi/3 радиан = 3,14/3 = 1,0466
30° = pi/6 радиан = 3,14/6 = 0,5233
Или использовать готовую формулу
Angle to Radians => Angle *pi / 180 (формула)
pi/180 = 3,14/180 = 0,01744 (коэффициент, записан в варе в переменную-множитель bj_DEGTORAD)
_________________
Чтобы перевести из радиан в градусы
Использую формулу
Radians to Angle => Radians * 180 / pi
1 радиан = 57,32°
0,5 радиан = 0,5 * 180/3,14 = 28,6°
Используют точно также переменную-множитель bj_RADTODEG, но с другим названием. Там было Deg to Rad (перевести в радианы), здесь Rad to Deg (в градусы)
тут есть погрешности до десятичных, до сотых и более. Поэтому может не соответствовать. Это как пример. Считал сам. А вообще юзайте готовые переменные и не морочьте голову. На луа math.deg(rad) math.rad(deg)
Расстояние между двумя точками
Дано: Даны координаты двух точек (0,0),(1,1). Найдите расстояние между ними.
Ответ: 1.4142135623730951
Решение
function VectorLength(x1,y1,x2,y2)
    return ((x2-x1)^2 + (y2-y1)^2)^0.5
end
print(VectorLength(0,0,1,1)) --печает 1.4142135623730951
Полярный угол точки
Даны два числа – координаты точки (2,3), не совпадающей с началом координат (0,0). Выведите ее полярный угол (величину от 0 до 2π).
Ответ: 0.982793723247329
Решение:
--Полярный угол точки x,y строится относительно начала координат (0,0). Вычитать (x-0,y-0) бесполезно, можно сразу указать в atan2(y,x)
function p_angle(x,y)
	return math.atan2(y,x)
end
print(p_angle(2,3))
Угол вектора-отрезка или угол между двумя точками через atan2
Решение: здесь тоже такое решение, как и с полярным углом точки, только тут указываем вектор в аргументах atan2(dy,dx)
--Угол между двумя точками
function BlzAngleBetweenPoints(x1,y1,x2,y2)
    return math.atan2(y2-y1, x2-x1) 
end
Угол между векторами (скалярное произведение векторов) через acos
Даны четыре числа: координаты двух невырожденных векторов.
пример-1 (2,1),(3,5) ответ: 0.5667292175235064
пример-2 (3,3),(-3,-3) ответ: 3.141592653589793
центр начала координат (0,0)
Так понимаю, что невырожденные векторы строятся относительно центра координат. Достаточно указать две точки.
--угол между двумя векторами
function AngleVectors(x1,y1,x2,y2)
    return math.acos((x1*x2+y1*y2)/((x1^2+y1^2)^0.5  * (x2^2+y2^2)^0.5))
end

print(AngleVectors(2,1,3,5)) --вернет 0.5667292175235064
print(AngleVectors(3,3,-3,-3)) --печает 3.141592653589793. в старой версии demo online-lua это мб не корректно работать. А в варике это норм работает
Пусть даны вектора a(ax, ay) и b(bx, by). Необходимо вычислить угол между ними.
Мы можем вычислить скалярное и векторное произведение данных векторов, и после этого, поделив на |a|·|b|, получить косинус и синус угла между ними соответственно, после чего воспользоваться функциями asin и acos. Но гораздо удобнее воспользоваться функцией языка программирования atan2, которая по двум числам y и x возвращает полярный угол точки (x, y), не требуя дополнительных вызовов функций.
Поэтому для нахождения угла между векторами достаточно вызвать atan2( |a, b|, |a, b| )
скалярное произведение векторов (dot product)
Скалярное произведение двух векторов a(ax,ay) и b(bx,by) определяется как
(a,b)=|a|*|b|*cos φ, где φ – угол между ними
Выражение скалярного произведение через координаты: (a,b)=ax*bx + ay*by
Легко видеть, что скалярное произведние линейно по каждому аргументу:
(a + b, c) = (a, c) + (b, c)
(ka, c) = k(a, c).
Аналогичные утверждение верны и для второго аргумента.
Поскольку косинус - четная функция, то скалярное произведение коммутативно:
(a, b) = (b, a).
Скалярное произведение необходимо использовать, когда нужно проверить два вектора (два отрезка, две прямые) на перпендикулярность, поскольку (a, b) = 0 тогда и только тогда, когда ненулевые вектора a и b перпендикулярны.
Скалярное произведение положительно, если угол между векторами - острый, и отрицательно, если тупой.
--направление вектора dot product (a*b=0 - перпендикулярна (ортогональны),a*b>0 - в одном напра-нии, a*b<0 - в противоположных) 
function scalar_product(x1,y1,x2,y2)
	return x1*x2 + y1*y2 --скалярное произведение векторов |a|*|b|*cos alpha. cos 0 = 1. 3 опер
end
векторное произведение векторов (cross product)
Векторным произведением двух трехмерных векторов a(ax, ay , az ) и b(bx, by , bz ) является вектор c с координатами (ay*bz − az*by , az*bx − ax*bz , ax*by − ay*bx). Этот вектор перпендикулярен плоскости, в которой расположены вектора a и b. Но мы рассматриваем геометрию на плоскости, поэтому результатом векторного произведения двух векторов, лежащих в плоскости XOY будет вектор, коллинеарный оси OZ, и поэтому его можно представить в виде одного числа - координаты cz .
Итак, всюду далее под векторным произведением мы будем понимать скалярную величину
[a, b] = ax*by − ay*bx.
Легко видеть, что векторное произведение можно выразить и по-другому:
[a, b] = |a| · |b| · sin φ.
В данном случае φ - ориентированный угол поворота вектора a в сторону вектора b, то есть если поворот производится по часовой стрелке, то векторное произведение положительно, а если против часовой стрелки - то отрицательно.
Векторное произведение линейно по каждому аргументу и антикоммутативно:
[a, b] = −[b, a].
Векторное произведение удобно использовать для проверки коллинеарности векторов (прямых, отрезков), поскольку оно равно нулю тогда, и только тогда, когда два вектора коллинеарны.
Если векторное произведение [a, b] положительно, то вектор b получается из вектора a вращением в положительном направлении (против часовой стрелки), если отрицательно  вращением в отрицательном направлении (по часовой стрелке).
Также легко видеть, что векторное произведение можно использовать для вычисления площади треугольника:
S(△ABC) = 1/2[AB, AC]
(можно взять и другие два вектора, составляющие стороны треугольника).
--псевдовекторное произведение cross product
function cross(x1,y1,x2,y2)
	return x1*y2 - y1*x2 
end
Угол между двумя векторами с 3 точками: общая точка (x0,y0), и два конца каждого вектора (x1,y1),(y2,y2).
Решение: используем скалярное произведение вектора, только в вргументах указываем dx,dy. где вместо dx1=x1-x0, dy1=y1-y0, dx2=x2-x0, dy2=y2-y0
--Угол между 2 векторами, угол между направлениями этих векторов (наименьший угол).
--По определению, угол между двумя векторами находится в промежутке [0°; 180°].
--Косинус угла между ними равен
--@param real dx1,dy1,dx2,dy2
---@return real
function AngleBetweenTwoVectors(dx1,dy1,dx2,dy2) --в радианах (для превращения в градусы заверните в Acos)
    return math.acos((dx1*dx2+dy1*dy2)/((dx1^2+dy1^2)^0.5  * (dx2^2+dy2^2)^0.5))
end

--Угол между двумя отрезками
function BlzAngleBetweenSegments(Ax1,Ay1,Ax2,Ay2,Bx1,By1,Bx2,By2)
    local dx1,dx2,dy1,dy2=Ax2-Ax1,Bx2-Bx1,Ay2-Ay1,By2-By1
    return AngleBetweenTwoVectors(dx1,dy1,dx2,dy2)

end
--угол между диагоналями четырехугольника/сторонами треугольника и пр
--cx,cy - точка пересечения диагоналей A и B
--Ax,Ay,Bx,By - одна из крайних точек диагоналей
function BlzAngleBetweenDiagonals(cx,cy,Ax,Ay,Bx,By)
    local dx1,dx2,dy1,dy2=Ax-cx,Bx-cx,Ay-cy,By-cy --4 опер
    return AngleBetweenTwoVectors(dx1,dy1,dx2,dy2)
end
Площадь треугольника
Даны координаты трёх точек, которые могут лежать на одной прямой и даже совпадать.
пример-1 (1,0),(2,4),(5,2) ответ: 7.0
пример-2 (0,0),(0,0),(0,0) ответ: 0
векторное произведение можно использовать для вычисления площади треугольника:
S(△ABC) = 1/2[AB, AC]
(можно взять и другие два вектора, составляющие стороны треугольника).
S = math.abs((x2-x1)*(y3-y1) - (x3-x1)*(y2-y1))/2
--Площадь треугольника по координатам с помощью формулы
function TriS(x1,y1,x2,y2,x3,y3)
    return math.abs(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2))/2 --10 опер
end

print(TriS(1,0,2,4,5,2)) --вернет 7.0
print(TriS(0,0,0,0,0,0)) --вернет 0
7. Классификация векторов (коллинеарны, перпендикулярны)
Даны четыре числа: координаты двух ненулевых векторов. Если эти вектора коллинеарны, выведите 1. Если эти вектора перпендикулярны, выведите 2. Иначе выведите 0.
В этой задаче нельзя использовать обратные тригонометрические функции.
пример-1: (1,1),(2,2) ответ: 1
пример-2: (0,1),(1,0) ответ: 2
пример-3: (1,2),(2,1) ответ: 0
решение:
--вектора коллинеарны, если равны 0
--Вектора, параллельные одной прямой или лежащие на одной прямой
function IsVectorsCollinear(x1,y1,x2,y2)
	return x1*y2 - y1*x2 == 0 --уравнение составлено из условия x1/x2=y1/y2. 4 опер.
end

--направление вектора dot product (a*b=0 - перпендикулярна (ортогональны),a*b>0 - в одном напра-нии, a*b<0 - в противоположных) 
function scalar_product(x1,y1,x2,y2)
	return x1*x2 + y1*y2 --скалярное произведение векторов |a|*|b|*cos alpha. cos 0 = 1. 3 опер
end
--псевдовекторное произведение cross product
function cross(x1,y1,x2,y2)
	return x1*y2 - y1*x2 
end

function class_vectors(x1,y1,x2,y2)
	
	if scalar_product(x1,y1,x2,y2) == 0 then
		return 2 --если вектора перпендикулярны, равно 2
	elseif IsVectorsCollinear(x1,y1,x2,y2) then
		return 1 --если вектора коллинеарны, равно 1
	else
		return 0
	end
end

print(class_vectors(1,1,2,2)) --вернет 1
print(class_vectors(0,1,1,0)) --вернет 2
print(class_vectors(1,2,2,1)) --вернет 0
поворот вектора
ссылка
вики
Пусть вектор имеет координаты (x, y), тогда
x = r cos φ,
y = r sin φ,
где r - длина вектора, φ - полярный угол.
Определим, какие координаты будут у вектора, если его повернуть на угол α. После поворота длина вектора не изменится, а полярный угол будет равен φ + α. Поэтому новые координаты вектора (x′, y′) можно вычислить по формулам:
x′ = r cos(φ + α) = r cos φ cos α − r sin φ sin α = x cos α − y sin α,
y′ = r sin(φ + α) = r cos φ sin α + r sin φ cos α = x sin α + y cos α
функции поворота точки
Даны три числа: координаты точки и угол (в радианах, задан в виде действительного числа).
Выведите координаты точки, полученной поворотом данной точки вокруг начала координат на данный угол в положительном направлении.
Ввод
1 0
1.5707963267948966
Ответ: 0.0 1.0
function PointTurn(x,y,a)
	local c,s=math.cos(a),math.sin(a)
	local x1= x*c - y*s
	local y1= x*s + y*c
	return x1,y1
end
print(PointTurn(1,0,1.5707963267948966)) --Ответ: 0.0 1.0. Вместо ноль может выдать 6.1232339957368e-17, ничего страшного, это 0.000000...0612
функции поворота вектора
тут происходит поворот не вокруг одной точки, а относительно другой точки.
пример
Например повернуть точку относительно центра можно с помощью вектора. есть две индентичные функции поворота
--Поворот точки против часовой стрелки вокруг другой точки
function turnof(x,y,alpha,cx,cy)
	local tx,ty=PointTurn(x-cx,y-cy,alpha)
    tx = tx+ cx;
    ty = ty+ cy;
    return tx,ty
end
--поворот вектора
function PointTurnVector(x1,y1,x2,y2,a)
	local c,s=math.cos(a),math.sin(a)
	local vx,vy=x2-x1,y2-y1
	local px= vx*c − vy*s
	local py= vx*s + vy*c
	return px,py
end
полярное смещение
всеми известное варкрафтерами функция:
x=x+r*cos(a)
y=y+r*sin(a)
можно поворачивать вокруг ±a, так и ±r отдалять/приближать вектор.
function PolarOffset(x,y,r,a)
	local c,s=math.cos(a),math.sin(a)
	x= x+r*c
	y= y+r*s
	return x,y
end
3ds полярное смещение
это те же самые полярные координаты, только добавляется z с углом наклона b. Таким образом превращаясь из полярных в сферических координат
function PolarProjectionXYZ(x, y, z, dist, GroundAngle, FacingAngle)
    --FacingAngle - 0-360 -- yaw
    --GroundAngle - 0-180 -- pitch
    local x1 = x + dist*SinBJ(GroundAngle)*CosBJ(FacingAngle)
    local y1 = y + dist*SinBJ(GroundAngle)*SinBJ(FacingAngle)
    local z1 = z + dist*CosBJ(GroundAngle)
    --
    return x1,y1,z1
end
УРАВНЕНИЯ
Уравнение прямой.
общее уравнение прямой ax+by+c=0
Классическое задание прямой y = kx + b в виде пары чисел (k, b) не употребляется, поскольку таким образом невозможно задать прямую, параллельную оси OY .
Как правило, прямая задается тремя числами (a, b, c), являющимися коэффициентами уравнения: ax+by+c=0
ВЫВОДЫ:
  1. Прямая на плоскости является линией первого порядка. В общем случае она задается уравнением Ax+By+C = 0, где A,B,C – числа.
  2. Коэффициенты A и B не обращаются в ноль одновременно, так как с геометрической точки зрения это координаты вектора, перпендикулярного прямой. Вектор, перпендикулярный прямой, называют нормальным вектором этой прямой.
ИССЛЕДОВАНИЕ ОБЩЕГО УРАВНЕНИЯ ПРЯМОЙ.
Если в уравнении Ax+By+C = 0 все коэффициенты A,B и C отличны от нуля, то уравнение называют полным; если хотя бы один из коэффициентов равен нулю – уравнение называют неполным.
  1. Пусть общее уравнение прямой – полное. Тогда его можно записать в виде
x/a + x/b = 1 (5)
С геометрической точки зрения a и b – отрезки, отсекаемые прямой на координатных осях Ox и Oy соответственно. Уравнение (5) называют уравнением прямой в отрезках.
  1. Пусть в общем уравнении прямой коэффициенты A и B – ненулевые, а C = 0, т.е. уравнение прямой имеет вид
Ax+By = 0
Такая прямая проходит через начало координат O (0;0).
  1. Пусть в общем уравнении прямой один из коэффициентов A или B – нулевой, а C ≠ 0, т.е. уравнение прямой имеет вид
Ax+C = 0 или By+C = 0.
Эти уравнения можно записать в виде
x = a и y = b .
Таким образом, прямая в уравнении которой отсутствует одна из координат, параллельна оси отсутствующей координаты
  1. Пусть в общем уравнении прямой C = 0 и один из коэффициентов A или B тоже нулевой, т.е. уравнение прямой имеет вид Ax = 0 или By = 0.
Эти уравнения можно записать в виде
x = 0 (уравнения координатной оси Oy)
и y = 0 (уравнения координатной оси Ox).
Замечание. Пусть прямая ℓ не проходит через O(0;0).
Обозначим:
  1. P0 (x0;y0 ) – основание перпендикуляра, опущенного на ℓ из
начала координат,
  1. n̄ = {cosα, cosβ} – орт вектора OP0,
  2. p=|OP0| – расстояние от начала координат до прямой ℓ
Тогда уравнение ℓ можно записать в виде
cosα·x + cosβ·y + C = 0,
где C = – p (доказать самим).
Этот частный случай общего уравнения прямой называется нормальным уравнением прямой.
нормальное уравнение прямой
Нормальное уравнение прямой на плоскости, расстояние от точки до прямой
Пусть дана некоторая прямая L. Проведём через начало координат прямую n, перпендикулярно данной и назовём её нормалью к прямой L. Буквой N отметим точку, в которой нормаль пересекает прямую L. На нормали введём направление от точки O к точке N.
Обозначим через α угол, на которой нужно повернуть против часовой стрелки ось Ox до совмещения её положительного направления с направлением нормали, через p длину отрезка ON.
Тогда уравнение
x*cosα + y*cosβ - p = 0. (1)
будет нормальным уравнением прямой.
С помощью нормального уравнения прямой можно определить расстояние от данной точки плоскости до прямой. Пусть M0(x0,y0) - точка, не лежащая на прямой, заданной нормальным уравнением. Требуется определить расстояние d от точки до прямой. Это расстояние определяется по формуле
d = |x0*cosα + y0*cosβ - p|. (2)
Общее уравнение прямой можно привести к нормальному виду. Пусть
Ax+By+C=0 - общее уравнение прямой, а x*cosα + y*cosβ - p = 0 - её нормальное уравнение.
Так как оба уравнения определяют одну и ту же прямую, их коэффициенты пропорциональны.
Очевидно, для получения нормального уравнения следует все члены общего уравнения умножить на постоянный множитель u, вычисляемый по формуле
u = ± 1 / sqrt(A^2 + B^2)
В этой формуле берётся знак, противоположный знаку C в общем уравнении прямой.
Таким образом, получаем уравнение
u*Ax + uBy + uC = 0
которое и будет нормальным уравнением прямой на плоскости.
Другие формы записи уравнения прямой на плоскости
1 Параметрические уравнения прямой
ЗАДАЧА. Записать уравнение прямой, проходящей через точку M0 (x0 ;y0 ), параллельно вектору ℓ̄ = {m; n} .
Вектор, параллельный прямой, называют направляющим вектором этой прямой.
Уравнение r̄ = r̄0 + t ⋅ ℓ̄ и систему уравнений
x=x0+t*m,
y=y0+t*n,
называют параметрическими уравнениями прямой (в векторной и координатной форме соответственно).

Пусть дана точка A0(x0, y0) и направляющий вектор p(px, py ). Пусть t - произвольное действительное число, тогда вектор tp коллинеарен вектору p, и все точки на прямой можно получить откладывая от точки A0 вектор tp для всевозможных значений t. Тогда координаты точки A(x, y) будут иметь вид:
x(t) = px*t + x0,
y(t) = py*t + y0.
Такой способ задания прямой, где координаты x и y выражаются, как функции от независимого параметра t называется параметрическим заданием.
2 Каноническое уравнение прямой на плоскости
Пусть в задаче 2 вектор ℓ̄ не параллелен ни одной из координатных осей (т.е. m ≠ 0 и n ≠ 0).
Уравнение (x-x0)/m = (y-y0)/n называют каноническим уравнением прямой на плоскости.
3 Уравнение прямой, проходящей через две точки – частный случай канонического уравнения прямой
Пусть прямая проходит через две точки M1 (x1,y1) и M2 (x2,y2).
Уравнение (x-x1)/(x2-x1) = (y-y1)/(y2-y1) называют уравнением прямой, проходящей через две точки M1 (x1 ,y1 ) и M2 (x2 ,y2 ) .
4 Уравнение прямой с угловым коэффициентом
Пусть прямая ℓ не параллельна оси Ox. Тогда она пересекается с Ox, образуя при этом две пары вертикальных углов.
Угол φ , отсчитываемый от оси Ox к прямой ℓ против часовой стрелки, называют углом наклона прямой ℓ к оси Ox.
Число k = tg φ (если оно существует, т.е. если прямая ℓ не параллельна оси Oy) называют угловым коэффициентом прямой.
Для прямой, параллельной оси Ox, угол наклона прямой к оси Ox считают равным нулю. Следовательно, угловой коэффициент такой прямой k = tg0 = 0
Пусть прямая ℓ не параллельна оси Ox и Oy и проходит через точки M1 (x1 ,y1 ) и M2 (x2 ,y2) (где x1 < x2 ). Найдем угловой коэффициент этой прямой
Получили: k= tg φ = (y2-y1)/(x2-x1)
Уравнение прямой, проходящей через две точки перепишем в виде:
(y-y1)=k*(x-x1) - это уравнение прямой, проходящей через точку M1 (x1 ,y1 ) и имеющей угловой коэффициент k.
Перепишем это уравнение в виде y = kx + b (где b = y1 – kx1 ).
Его называют уравнением прямой с угловым коэффициентом. С геометрической точки зрения b – отрезок, отсекаемый прямой на оси Oy.
Замечание.
Уравнение прямой с угловым коэффициентом было получено в предположении, что прямая не параллельна оси Ox и Oy.
Для прямой, параллельной Ox общее уравнение можно рассматривать как уравнение с угловым коэффициентом.
Действительно, уравнение такой прямой
y = b или y = 0 · x + b,
где k = 0 – угловой коэффициент прямой.
Нормаль к прямой и направляющий вектор
Рассмотрим прямую ax+by+c и произвольные две точки на этой прямой: A0(x0, y0) и A1(x1, y1). Поскольку ax0 + by0 + c = 0, ax1 + by1 + c = 0, то
a(x0 − x1) + b(y0 − y1) = 0.
Последнее равенство означает, что вектор n(a, b) ортогонален вектору (x0 − x1, y0 − y1), то есть вектор n ортогонален нашей прямой. Такой вектор называется нормалью или вектором нормали.
Легко видеть, что вектор p с координатами (−b, a) ортогонален вектору n, так как
(p, n) = −ba+ab = 0,
то есть вектор p параллелен прямой. Такой вектор будем называть направляющим вектором.
Итак, для прямой ax+by +c нормальным вектором является вектор n(a, b), а направляющим - вектор p(−b, a), а также любые вектора, полученные из данных умножением на ненулевое число.
function NormalVectorLine(a,b,c)
	return a,b
end
function ParallelVectorLine(a,b,c)
	return -b,a
end
Вектор нормали (перпендикулярный).
Уравнение прямой по точке и вектору нормали
Уравнение вид а называется общим уравнением прямой на плоскости. При различных численных значениях A, B и C, в том числе нулевых, оно может определять всевозможные прямые без исключения.
Одна из фундаментальных задач аналитической геометрии - составление общего уравнения прямой по точке, ей принадлежащей, и вектору нормали.
Вектор нормали - это вектор, перпендикулярный искомой прямой. Вектор нормали чаще всего записывается так: n(n1,n2). Координаты точки - и .
Общее уравнение прямой на плоскости по точке и вектору нормали составляется по формуле:
n1*(x-x0) + n2*(y-y0)=0 (1).
1.2 Уравнение прямой, заданной одной из ее точек вектором и вектором нормали к ней
Пусть заданная точка P0 прямой имеет координаты (x0,y0), а некоторый вектор нормали n к ней (то есть вектор, оторгональный нашей прямой) - координаты (a,b).
Если P(x,y) - произвольная точка на нашей прямой, то координаты вектора P0P равны (x-x0,y-y0). Тогда скалярное произведение векторов можно выразить так:
(n,P0P)=a*(x-x0)+b*(y-y0)=0 (6)
Очевидно, что уравнение прямой (6) также несложно привести к виду (4).
Напомню формулу
ax+by+c=0 (4)
где a = y2-y1, b=x1-x2, c=x1*(y1-y2) + y1*(x2-x1)
Тогда становится понятно, что коэффициенты a и b из уравнения (4) представляют собой координаты одного из векторов нормали к описываемой данным уравнением прямой. Отсюда и следует, что при любых значениях коэффициентов a,b, и с (кроме a=b=0) уравнение (4) задает прямую. Ею будет прямая перпендикулярная вектору (a,b) и проходящая через точку, чью координаты удотвлетворяют (4). При a≠0 такой точкой будет, например точка (-c/a,0), при a=0 - точка (0,b/c).
пример:
Несмотря на то, что постановка задачи на первый взгляд кажется несколько искусственной, именно с помощью ее получили инструмент для решения целого ряда задач.
примеры
Пример 1. Составить общее уравнение прямой на плоскости, если она проходит через точку M(-3,5) и вектор нормали к ней n(2,-8).
Решение. Используя формулу (1), получаем:
2(x+3)-8(y-5)=0
2x+6-8y+40=0
x-4y+23=0
Из примера 1 видно, что координаты вектора нормали пропорциональны числам A и B из общего уравнения прямой на плоскости. Это не совпадение, а закономерность! Поэтому в общем случае, если известно общее уравнение прямой на плоскости, то вектор нормали к прямой можно записать так: n(A,B).

Пример 2. Задано общее уравнение прямой на плоскости: 3x+11y-4=0. Записать вектор нормали к этой прямой.
Решение. В заданном уравнении A=3, B=11. Поэтому вектор нормали запишется:
n(3,11).
направляющий вектор (параллельный вектор)
Уравнение прямой по точке и направляющему вектору
Если вектор нормали перпендикулярен искомой прямой, то направляющий вектор параллелен ей. Направляющий вектор обычно записывается так: p(p1,p2). Имеет место следующая зависимость координат направляющего вектора от чисел A и B общего уравнения прямой: p(-B,A).
Общее уравнение прямой по точке M0(x0,y0) и направляющему вектору можно составить по формуле
(x-x0)/p1 = (y-y0)/p2, (2)
известной как каноническое уравнение прямой на плоскости.
примеры
Пример 3. Составить общее уравнение прямой на плоскости, если она проходит через точку M0(-2,3) и её направляющий вектор p=(4,5).
Решение. Используя формулу (2), имеем:
(x+2)/4 = (y-3)/5
Далее путём преобразований получаем:
x/4 + 1/2 = y/5 - 3/5
x/4 - y/5 + 1/2 + 3/5 = 0
5x/20 - 4y/20 + 10/20 + 12/20 = 0
5x - 4y + 22 = 0
На всякий случай сделаем проверку - подставим в полученное общее уравнение прямой координаты точки, которая должна ей принадлежать:
-10-22+22 = 0
Получили верное равенство. А координаты вектора связаны с числами A и B уравнения закономерностью p(-B,A). Значит, задание выполнено корректно.

Пример 4. Задано общее уравнение прямой на плоскости: 7x-4y+3=0. Записать направляющий вектор к этой прямой.
Решение. В заданном уравнении A=7, B=-4. Поэтому направляющий вектор запишется: p(4,7).
Решая задачи контрольных работ, особенно, если задач много и к концу контрольной студент стремится наверстать упущенное за время обдумывания заданий, можно запутаться в знаках, записывая вектор нормали и направляющий вектор. Будьте внимательны!
преобразования из одной формы записи уравнения прямой в другую
Построить в прямоугольной системе координат на плоскости прямую, заданную общим уравнением ax+by+c=0
Как получить из коэффициентов общего уравнения две точки прямой?
Примеры
Построить в прямоугольной системе координат на плоскости прямую, заданную общим уравнением x -2y +8 = 0
Решение. Для построения прямой достаточно знать координаты каких-либо двух точек, например, точек пересечения прямой с координатными осями. Полагая в данном уравнении x=0, получим y=4, т.е. A(0,4) - точка пересечения прямой с осью Oy.
При y=0 получим x=-8, т.е. B(0,-8) - точка пересечения прямой с осью Ox.
По двум точкам и строим прямую (рисунок слева.)
Вектором нормали этой прямой служит вектор n(1,2)

Пример, есть две прямые с 2 наборами к-тов:
a (1,1) и b (2,2)
(x - xa) / (xb - xa) = (y - ya) /( yb - ya)
подставляем
(x - 1) / (2 - 1) = (y - 1) / (2 - 1)
В итоге получено каноническое уравнение прямой:
(x - 1)/1 = (y - 1)/1
Из уравнения прямой в каноническом виде получим уравнение прямой с угловым коэффициентом:
y = x

Пример, есть две прямые с 2 наборами к-тов:
a (1,1) и b (2,2)
Подставим в формулу координаты точек:
(x - 1)/(2 - 1) = (y - 5)/(2 - 5)
В итоге получено каноническое уравнение прямой:
(x - 1)/1 = (y - 5)/-3
Из уравнения прямой в каноническом виде получим уравнение прямой с угловым коэффициентом:
y = -3x + 8
Если уже есть уравнение прямой с коэффициентами ax+by+c=0, то ничего больше и не нужно. Подставляем рандомные две координаты по x: x1,x2 в это уравнение, и получаем из уравнения y1,y2. Так получаем коорды двух точек, описывающую прямую. Точек на этой прямой может быть великое множество, но для нас важно любые 2 точки прямой
--Convert coefficient equation to 2 points 
function ConvertСoefficientEquation(a,b,c, xx1,xx2)
	local x1,x2,y1,y2 = xx1,xx1
	
	--если ввод в функцию не ввели, введем сами
	if not(xx1 and xx2) then 
		--рандомное число, теперь остается найти y1,y2
		x1,x2 = 1,1
	end
	
	if b~=0 then --полное уравнение
		y1=-a*x1-c/b
		y2=-a*x2-c/b
	else --не полное уравнение
		y1=-a*x1
		y2=-a*x2
	end
	return x1,x2,y1,y2
end
составить уравнение ax+by+c=0, имея лишь две координаты двух точек, через которых проходит прямая
источник
Пусть дан отрезок PQ, т.е. известны координаты его концов Px,Py,Qx,Qy.
Требуется построить уравнение прямой на плоскости, проходящей через этот отрезок, т.е. найти коэффициенты A, B, C в уравнении прямой:
Ax + By + C = 0
находим коэффициенты
Заметим, что искомых троек (A,B,C), проходящих через заданный отрезок, бесконечно много: можно умножить все три коэффициента на произвольное ненулевое число и получить ту же самую прямую. Следовательно, наша задача — найти одну из таких троек.
Нетрудно убедиться (подстановкой этих выражений и координат точек P и Q в уравнение прямой), что подходит следующий набор коэффициентов:
A = Py - Qy,
B = Qx - Px,
C = - A*Px - B*Py
--ax + by + c = 0
function EquationCoefficients(Px,Py,Qx,Qy)
	local A,B = Qy-Py, Px-Qx
	C = -(A*Px + B*Py)
	return A,B,C
end
print(EquationCoefficients(1,2,3,1))
находим коэффициенты (Целочисленный случай)
Важным преимуществом такого способа построения прямой является то, что если координаты концов были целочисленными, то и полученные коэффициенты также будут целочисленными. В некоторых случаях это позволяет производить геометрические операции, вообще не прибегая к вещественным числам.
Однако есть и небольшой недостаток: для одной и той же прямой могут получаться разные тройки коэффициентов. Чтобы избежать этого, но не уходить от целочисленных коэффициентов, можно применить следующий приём, часто называемый нормированием. Найдём наибольший общий делитель чисел |A|, |B|, |C|, поделим на него все три коэффициента, а затем произведём нормировку знака: если A<0 или A=0, B<0, то умножим все три коэффициента на -1. В итоге мы придём к тому, что для одинаковых прямых будут получаться одинаковые тройки коэффициентов, что позволит легко проверять прямые на равенство.
Если нужно привести в соответствующий вид уравнение, то надо использовать другую функцию вместо EquationCoefficients на EquationIntCoefficients, которая нормирует коэ-ты и знаки. EquationCoefficients просто преобразует коэ-ты, но ничего не нормирует.
пример:
8x -64y + 296 =0 /8 --делим на число 8 - это НОД
x -8y +37=0 -так нормируют коэ-ты
или
-3x +y +1 = 0 /-1 --надо знак нормировать, для удобства чтения
3x -y -1 = 0
--наименьший общий делитель между a,b gcd>0
function gcd(a, b)
	return b==0 and a or gcd(b,a%b)
end
--наименьший общий делитель между a,b,c
function nod(a, b, c)
	return gcd(gcd(a,b),c)
end

function EquationIntCoefficients(Px,Py,Qx,Qy)
	--находим коэ-ты уравнения
	local A,B = Py-Qy, Qx-Px
	local C = -A*Px - B*Py
	--далее нормируем коэ-ты
	
	--находим наибольший общий делитель 3 чисел
	local Z = nod(A,B,C)
	
	--коэф-ты делить на НОД
	A,B,C=A/Z,B/Z,C/Z
	
	--произведем нормировку знака
	if A<0 or (A==0 and B<0) then
		return -A,-B,-C
	end
	return A,B,C
end
print(EquationIntCoefficients(1,2,3,1))
получить коэффициенты (Вещественнозначный случай)
При работе с вещественными числами следует всегда помнить о погрешностях.
Коэффициенты A и B получаются у нас порядка исходных координат, коэффициент C — уже порядка квадрата от них. Это уже может быть достаточно большими числами, а, например, при пересечении прямых они станут ещё больше, что может привести к большим ошибкам округления уже при исходных координатах порядка 10^3.
Поэтому при работе с вещественными числами желательно производить так называемую нормировку прямой: а именно, делать коэффициенты такими, чтобы A^2 + B^2 = 1. Для этого надо вычислить число Z:
Z = sqrt( A^2 + B^2 ),
и разделить все три коэффициента A, B, C на него.
Тем самым, порядок коэффициентов A и B уже не будет зависеть от порядка входных координат, а коэффициент C будет того же порядка, что и входные координаты. На практике это приводит к значительному улучшению точности вычислений.
Наконец, упомянем о сравнении прямых — ведь после такой нормировки для одной и той же прямой могут получаться только две тройки коэффициентов: с точностью до умножения на -1. Соответственно, если мы произведём дополнительную нормировку с учётом знака (если A<-epsilon или |A|< epsilon, B<- epsilon, то умножать на -1), то получающиеся коэффициенты будут уникальными.
функция EquationFloatCoefficients аналогична EquationIntCoefficients, однако, мне трудно поручиться за точность. Обычно с целыми коэффициентами работаю. Как автор статьи написал, так и написал.
EPS = 1E-9;
function EquationFloatCoefficients(Px,Py,Qx,Qy)
    local A,B = Py-Qy,Qx-Px
    local C,Z = -A*Px-B*Py , (A^2 + B^2)^0.5
    
	if A< EPS or (math.abs(A)<EPS and B<-EPS) then
		return -A/Z,-B/Z,-C/Z
	end
    return A/Z,B/Z,C/Z
end
print(EquationFloatCoefficients(1,2,3,1))
Преобразование уравнения прямой с угловым коэффициентом в общее уравнение прямой
Во многих задачах аналитической геометрии возникает необходимость преобразовать уравнения одного вида к уравнению другого вида. Преобразование уравнения прямой с угловым коэффициентом в общее уравнение прямой делается достаточно просто: в уравнении вида y=kx+b всё переносим в левую часть, а в правой остаётся нуль. Получается уравнение вида Ax+By+C=0.
Пример. Дано уравнение прямой с угловым коэффициентом y=14x-6. Записать уравнение этой прямой в общем виде и направляющий вектор этой прямой.
Решение. Всё переносим в левую часть, а в правой оставляем нуль:
14x-y-6=0
Получили общее уравнение прямой. В нём A(14),B(-1). Поэтому направляющий вектор запишется так: p(1,14).

небольшая заметка связи
чтобы проверять пересекаются или параллельны прямые, приходилось сравнивать углы.
Уравнение прямой имеет следующий вид: y = kx + b, где k — угловой коэффициент, b — координата «y» точки пересечения прямой с осью Oy
тут идет сравнение угловых коэф-тов
k1==k2 --косое произведение коллинеарности
(x-x1)(y2-y1)-(y-y1)(x2-x1)=0 - косое произведение коллинеарности
или
(y2-y1)x + (x1-x2)y + x1(y1-y2)+y1(x2-x1)=0
или
ax+by+c=0
где a=y2-y1, b=x1-x2, c=x1(y1-y2)+y1(x2-x1)
КАК РАСПОЛОЖЕНЫ ОБЪЕКТЫ
Общая информация. взаимное расположение двух прямых
На плоскости две прямые могут:
а) быть параллельны,
б) пересекаться.
Пусть уравнения прямых ℓ1 и ℓ2 имеют вид:
ℓ1: A1x + B1y + C1 = 0 или y = k1x + b1
ℓ2: A2x + B2y + C2 = 0 или y = k2x + b2
1 Пусть прямые параллельны:
Получаем, что прямые ℓ1 и ℓ2 параллельны тогда и только тогда, когда в их общих уравнениях коэффициенты при соответствующих неизвестных пропорциональны, т.е.
A1/A2 = B1/B2
или
A1*B2=B1*A2 <= убираем знаменатели
или их угловые коэффициенты равны, т.е.
k1 = k2
2 Пусть прямые пересекаются
где знак плюс берется в том случае, когда надо найти величину острого угла, а знак минус – когда надо найти величину тупого угла.
Критерий перпендикулярности прямых, заданных общими
уравнениями:
(N1,N2)=A1*A2+B1*B2=0
где знак плюс берется в том случае, когда надо найти величину
острого угла, а знак минус – когда надо найти величину тупого
угла.
Критерий перпендикулярности прямых, имеющий угловые
коэффициенты k1 и k2 :
k2=-1/k1
проверка: две прямые перпендикулярны
уравнение прямой, перпендикулярной данной и проходящей через заданную точку
Пусть заданная точка P0 искомой прямой имеет координаты (x0,y0). Если P (x,y) - произвольная точка на той же прямой, то координаты вектора P0P равны (x-x0,y-y0). Этот вектор P0P перпендикулярен вектору P1P2, где P1(x1,y1) и P2(x2,y2) - точки на данной прямой. Тогда скалярное произведение векторов (P1P2,P0P) можно выразить так:
(x2-x1)*(x-x0) + (y2-y1)*(y-y0)=0
или
(x2-x1)*x + (y2-y1)*y - (x2-x1)*x0 + (y2-y1)*y0=0
вариант 1
function PerpendicularLines(x,y,x0,y0,x1,y1,x2,y2)
	return (x2-x1)*(x-x0) + (y2-y1)*(y-y0)==0
end

print(PerpendicularLines(5,1,5,0,0,0,10,0)) --печает true. P0 лежит на прямой P1P2
print(PerpendicularLines(5,1,5,1,0,0,10,0)) --P0 изменена, теперь не лежит на прямой P1P2, но все равно выводит true. что приводим к выводу, что происходит определение пересечения двух прямых, созданными векторами P0P и P1P2
print(PerpendicularLines(3,1,5,1,0,0,10,0)) --P изменена, теперь не принадлежит прямой P0P. печается false
вариант 2
function PerpendicularLines2(x,y,x0,y0,x1,y1,x2,y2)
	return (x2-x1)*x + (y2-y1)*y + (x2-x1)*x0 + (y2-y1)*y0==0
end

print(PerpendicularLines2(5,1,5,0,0,0,10,0)) --печает true. P0 лежит на прямой P1P2
print(PerpendicularLines2(5,1,5,1,0,0,10,0)) --P0 изменена, теперь не лежит на прямой P1P2, но все равно выводит true. что приводим к выводу, что происходит определение пересечения двух прямых, созданными векторами P0P и P1P2
print(PerpendicularLines2(3,1,5,1,0,0,10,0)) --P изменена, теперь не принадлежит прямой P0P. печается false
Уравнение перпендикулярной прямой
Прямая, проходящая через точку M1(x1; y1) и перпендикулярная прямой y=ax+b, представляется уравнением
y–y1=-1/a(x-x1) (1)

Альтернативная формула
Прямая, проходящая через точку M1(x1; y1) и перпендикулярная прямой Ax+By+C=0, представляется уравнением
A(y-y1)-B(x-x1)=0 (2)
для проверки, что линии перпендикулярны, достаточно проверки коэ-тов из уравнении двух прямых ax + by + c = 0
(a1 * a2 + b1 * b2) == 0 --линии перпендикулярны источник
или
a*(x0 - x1) + b*(y0 - y1) = 0.
проверка: две прямые параллельны (иначе они пересекаются)
Две прямые на плоскости называются параллельными, если они не пересекаются.
Признаки параллельности двух прямых:
  1. Если при пересечении двух прямых секущей, накрест лежащие углы равны, то прямые параллельны.
  2. Если при пересечении двух прямых секущей, соответственные углы равны, то прямые параллельны.
  3. Если при пересечении двух прямых секущей, сумма односторонних углов равна 180°, то прямые параллельны.
Решение:
источник
При помощи линейного уравнения
Линейная функция вида y = kx + b
k = (y2 - y1)/(x2 - x1) - угловой коэ-т прямой
b - наскока поднимает/отпускаем прямую от начала координат (0,0)
Линейной функцией называется функция вида y = kx + b, заданная на множестве всех действительных чисел. Здесь k – угловой коэффициент (действительное число), b – свободный член (действительное число), x – независимая переменная.
1 Сравнение угловых коэффициентов двух прямых
k = (y2 - y1)/(x2 - x1) (1) - угловой коэ-т прямой
(y2 - y1)/(x2 - x1) == (y - y0)/(x - x0) (2)
умножение быстрее деления, поэтому приводим в другой вид:
(y2 - y1)*(x - x0) == (y - y0)*(x2 - x1) (3)
проверка парралельности прямых, где запись уравнения выражена 2 точками
function ParallelLines(x,y,x0,y0,x1,y1,x2,y2)
	return (y2 - y1)*(x - x0) == (y - y0)*(x2 - x1)
end

print(ParallelLines(2,1,4,1,2,4,4,4)) --печает true
print(ParallelLines(2,0,4,1,2,4,4,4)) --печает false
2 для двух линейных уравнении типа ax+by+c=0 источник
Прямые параллельны другу друг и не имеют точек пересечения
(a1 * b2 - a2 * b1) == 0 (4) - эта преобразованная формула ни чем не отличается от формулы (3), что записана выше.
проверка парралельности прямых, где запись уравнения выражены коэф-тами уравнения ax+by+c=0
function ParallelLines(a1,b1,a2,b2)
	return (a1 * b2 - a2 * b1) == 0
end
10: Взаимное расположение точки и прямой (точка лежит на линии, либо справа или слева от линии). Три точки лежат на одной прямой
1.1 уравнение прямой, проходящей через две различные точки, заданными своими координатами:
С помощью косого произведения условие коллинеарности векторов можно выразить так:
(x-x1)*(y2-y1)-(y-y1)*(x2-x1)=0 - уравнение прямой, которая проходит через две точки
или
(y2-y1)*x + (x1-x2)*y + x1*(y1-y2) + y1*(x2-x1)=0

всякую прямую можно задать уравнением вида ax+by+c=0:
a=y2 − y1 , b=x1 − x2 , c = x1*(y1-y2) + y1*(x2-x1)

Пусть дана точка A0(x0, y0) и направляющий вектор прямой p(px, py ). Необходимо получить уравнение прямой в каноническом виде ax + by + c = 0.
Поскольку направляющий вектор имеет координаты (−b, a), то a = py , b = −px. Коэффициент c получим из условия ax0 + by0 + c = 0, откуда c = −py x0 + pxy0. Итак, уравнение прямой имеет вид:
py x − pxy − py x0 + pxy0 = 0.

Если даны две точки A0(x0, y0) и A1(x1, y1), то применив предыдущий результат для направляющего вектора A0A1 получим уравнение прямой:
(y1 − y0)x + (x0 − x1)y + (y0 − y1)x0 + (x1 − x0)y0 = 0,
то есть a = y1 − y0, b = x0 − x1, c = (y0 − y1)x0 + (x1 − x0)y0.
В параметрическом виде задание прямой будет иметь вид:
x(t) = x0 + (x1 − x0)t,
y(t) = y0 + (y1 − y0)t
Если величина t ≥ 0, то точка A(x(t), y(t)) лежит на луче, выходящем из точки A0 и проходящем через точку A1. Если кроме того t ≤ 1, то точка A лежит на отрезке A0A1. Если же t < 0, то точка A лежит на дополнении луча A0A1.
вариант 1 - условие коллинеарности вектора
function IsVectorsParallel(x1,y1,x2,y2)
	return x1*(y1-y2) + y1*(x2-x1)==0 --выполняется ли условие коллинеарности двух векторов 6 опер
end
вариант 2 (взаимное расположение точки и прямой)
--функция определения точки относительно отрезка
--Определяется так. Предположим, у нас есть 3 точки: А(х1,у1), Б(х2,у2), С(х3,у3). Через точки А и Б проведена прямая. И нам надо определить, как расположена точка С относительно прямой АБ. Для этого вычисляем значение:
-- Если D = 0 - значит, точка С лежит на прямой АБ.
-- Если D < 0 - значит, точка С лежит слева от прямой.
-- Если D > 0 - значит, точка С лежит справа от прямой.
function WherePoint(x1,y1,x2,y2,px,py)
    return (px - x1) * (y2 - y1) - (py - y1) * (x2 - x1) --8 опер
end

print(WherePoint(0,0,1,1,2,2)==0) --вернет true
вариант 3
--функция определения точки относительно вектора
--Q < 0 - точка справа (по часовой), Q > 0 - точка слева (против часовой)
local function Q(ax, ay, bx, by, atx, aty)
	return atx * (by - ay) + aty * (ax - bx) + ay * bx - ax * by
end
10.2 Взаимное расположение двух точек относительно прямой
Если точки находятся по разные стороны относительно прямой, то косые произведения имеют разные знаки, а значит их произведение отрицательно. Если же точки лежат по одну сторону относительно прямой, то знаки косых произведений совпадают, значит, их произведение положительно.
Итак:
  1. [P1P2, P1M1] * [P1P2, P1M2] < 0 – точки лежат по разные стороны.
  2. [P1P2, P1M1] * [P1P2, P1M2] > 0 – точки лежат по одну сторону.
  3. [P1P2, P1M1] * [P1P2, P1M2] = 0 – одна (или две) из точек лежит на прямой.
Кстати, задача об определении наличия точки пересечения у прямой и отрезка решается точно также. Точнее, это и есть эта же задача: отрезок и прямая пересекаются, когда концы отрезка находятся по разные стороны относительно прямой или когда концы отрезка лежат на прямой, то есть необходимо потребовать [P1P2, P1M1] * [P1P2, P1M2] ≤ 0.
первый способ
function WherePoint(x1,y1,x2,y2,px,py)
    return (px - x1) * (y2 - y1) - (py - y1) * (x2 - x1) --8 опер
end

--где x1,y1,x2,y2 - отрезок, определяющий направление прямой
--p1 и p2 - две точки, нужно определить как они расположены
function WhereTwoPointOnLine(x1,y1,x2,y2,p1x,p1y,p2x,p2y)
	return WherePoint(x1,y1,x2,y2,p1x,p1y)*WherePoint(x1,y1,x2,y2,p2x,p2y)>0
end

print(WhereTwoPointOnLine(0,0,0,100,-300,0,300,0))
print(WhereTwoPointOnLine(0,0,0,100,200,0,300,0))
лежат ли 2 точке по одной прямой ax+by+c=0
Даны две точки и уравнение прямой, точки не лежат на прямой. Выведите YES, если точки лежат по одну сторону от прямой и NO в противном случае.
Ввод
0 0
2 4
2 -1 -1
YES
Взаимное расположение точек M1(x1,y1) и M2(x2,y2) и прямой Ax + By + C = 0 можно определить по слекдующим признакам:
a) Ax1 + By1 + C1, Ax2 + By2 + C2 имеют одинаковые знаки
b) M1,M2 лежат по разные стороны от прямой, и имеют эти числа противоположные знаки.
c) одна или несколько из этих точек M1,M2 лежит-лежат на одной прямой, если оно из чисел равно нулю
--
function WhereTwoPointsLine(x1,y1,x2,y2,a,b,c)
	return x1*b + y1*a>=0 and x2*b + y2*a>=0
end
print(WhereTwoPointsLine(0,0,2,4,2,-1,-1)) --true
--составлено уравнение из точек (1,1),(5,1) -> x-1=0 или 1,0,-1
print(WhereTwoPointsLine(1,5,1,-5,1,0,-1)) -- -> false
print(WhereTwoPointsLine(1,5,1,5,1,0,-1)) -- -> true
совпадают ли прямые
Условие совпадение двух прямых
На плоскости заданы две прямые e1 и e2, общими уравнениями:
Ax1 + By1 + C1 = 0; Ax2 + By2 + C2 = 0. (1)
Очевидно, совпадение двух прямых есть частный случай параллельности. Поэтому должно быть A1/A2 = B1/B2 (2). Обозначая общую величину обоих отношений через t, имеем A1/A2=t, B1/B2=t (3),
Откуда A1=A2*t, B1=B2*t. Тогда уравнение системы (1) имеет вид
Ax2*t + By2*t + C1 = 0
или
Ax2 + By2 + C1/t = 0
Если уравнения (1) изображают одну и ту же прямую, то одни и те же координаты х, y удовлетворяют как уравнению (4), так и второму уравнению системы (1). Поэтому, если вычтем из уравнения (4) второе уравнение (1), то получим
C1/t=C2=0
или
C1=C2*t
Сопоставляя это с (3), находим
A1/A2 = B1/B2 = C1/C2
Это и есть условие совпадения двух прямых, которое говорит о том, что коэффициенты совпадающих прямых пропорциональны, то есть одно уравнение получается из второго путем умножения на некоторое постоянное число (число t не равно 0)
данные коэф-ты уравнения
--совпадающие линии - это одна и та же линия, только описана разными уравнениями
function MatchingLines(a1,b1,c1,a2,b2,c2)
	
	--коллинеарны ли линии
	if(a1 * b2 - a2 * b1) == 0 then
	    --проверка совпадают ли они
		return (a1 * b2 == b1 * a2 and a1 * c2 == a2 * c1 and b1 * c2 == c1 * b2)
	end
	return false
end
print(MatchingLines(1,2,3,-1,-2,-3))
данные точки прямых
--(ax1,ay1),(ax2,ay2) - точки прямой линии a
--(bx1,by1),(bx2,by2) - точки прямой линии b
function MatchingLines(ax1,ay1,ax2,ay2, bx1,by1,bx2,by2)
	--составляем коэффициенты уравнения прямой ax1+by1+c1=0
	local a1,b1=ay2-ay1,ax1-ax2
	local c1=ax1*(ay1-ay2)+ay1*(ax2-ax1)
	--составляем коэффициенты уравнения прямой ax2+by2+c2=0
	local a2,b2=by2-by1,bx1-bx2
	local c2=bx1*(by1-by2)+by1*(bx2-bx1)
	
	--коллинеарны ли линии
	if(a1 * b2 - a2 * b1) == 0 then
	    --проверка совпадают ли они
		return (a1 * b2 == b1 * a2 and a1 * c2 == a2 * c1 and b1 * c2 == c1 * b2)
	end
	return false
end
Классификация прямых
Программа получает на вход шесть чисел: коэффициенты уравнений двух прямых.
Программа должна вывести 1, если эти прямые совпадают, 2 – если параллельны, 3 – если перпендикулярны и 0 во всех остальных случаях.
Ввод
1 2 3
-1 -2 -3
Ответ: 1
function classLine(a1,b1,c1,a2,b2,c2)
	--коллинеарны ли линии
	if(a1 * b2 - a2 * b1) == 0 then
	    --проверка совпадают ли они
		if(a1 * b2 == b1 * a2 and a1 * c2 == a2 * c1 and b1 * c2 == c1 * b2)then
			return 1
		end
		return 2
	end
	--линии перпендикулярны
	if(a1 * a2 + b1 * b2) == 0 then
		return 3
	end
	return 0
end
print(classLine(1,2,3,-1,-2,-3))
Параллельность луча и прямой
Доказано что если луч и прямая параллельны друг другу, то у них нет общих точек. Чтобы установить параллельность луча и прямой достаточно сравнить их вектора направления. Если направление векторов совпадает, значит они коллинеарны т.е. параллельны или совпадают.
function CheckParralelRayAndLine(rayX,rayY,dirX,dirY,x1,y1,x2,y2)
	--вектор прямой
	local a = y2 - y1
	local b = x1 - x2
	--вектор луча
	local v = dirX - rayX
	local w = dirY - rayY

	return a*v + b*w == 0
end
Совпадение луча и прямой
Частный случай параллельности, когда луч и прямая совпадают. При совпадении они имеют бесконечное количество общих точек. Для программного кода программ и игр это значит, как такового пересечения нет, нет конкретных координат пересечения.
Если две точки луча лежат на прямой, значит луч и прямая совпадают. Подставим координаты луча в уравнение прямой. Если уравнение верно, то две контрольные точки луча лежат на прямой. Значит луч и прямая совпадают.
если
a*RayX + b*RayY + c = 0 и a*dirX + b*dirY + c = 0
Координаты луча являются решениями для уравнения прямой, значит две точки луча принадлежат прямой. Отсюда вывод: луч и прямая совпадают.
function MatchingRayAndLine(rayX,rayY,dirX,dirY,x1,y1,x2,y2)
	--вектор прямой
	local a = y2-y1
	local b = x1-x2
	local c = -x1*y2 + y1*x2
	return a*RayX + b*RayY + c == 0 and a*dirX + b*dirY + c == 0
end
Как построить точку, симметричную относительно прямой?
собственный способ по источнику
Задача состоит в том, чтобы найти координаты точки N, которая симметрична точке M(1,1) относительно прямой e: 3x+4y-12=0. Предлагаю выполнить действия самостоятельно, однако обозначу алгоритм решения с промежуточными результатами:
--вектор нормали (перпендикулярный)
function NormalVectorLine(a,b,c)
	return a,b
end

function PerpendicularLine(x1,y1,a,b,c)

	--снимаем вектор нормали из ax+by+c=0
	local x2,y2=NormalVectorLine(a,b,c)
	
	--уравнение составим по точке x1,y1 и направляющему вектору x2,y2
	
	--уравнение перпендикулярной линии ax1+by1+c1=0 
	local a1,b1,c1 = (y2-y1),(x1-x2),a*(y2-y1)+b*(x2-x1)
	
    --проверка, что линия перпендикулярна
	local p = a1*(x2-x1) + b1*(y2-y1)
	if p==0 then 
	    print("перпедикулярны "..p)
	else
	    print("не перпедикулярны "..p)
	end
	
	return a1,b1,c1
end
function LinesIntersect(a1,b1,c1, a2,b2,c2)
	local x = (b1 * c2 - b2 * c1) / (a1 * b2 - a2 * b1);
	local y = (a2 * c1 - a1 * c2) / (a1 * b2 - a2 * b1);
	return x,y
end
function PointOnLine(x,y,x1,y1,x2,y2)
	return(x - x1) * (y2 - y1) - (y - y1) * (x2 - x1)==0
end
function SymmetricalPointAboutLine(x,y,a,b,c)
	--Находим прямую line 2, которая перпендикулярна текущей прямой line 1.
	local a1,b1,c1=PerpendicularLine(x,y,a,b,c)
	--точка пересечения прямых
	local x0,y0=LinesIntersect(a1,b1,c1, a,b,c)
	--теперь находим симметричную точку, как известно x0,y0 - середина точки
	local px,py=2*x0-x,2*y0-y
	
	if PointOnLine(px,py,x0,y0,x,y) then
		print('симметричная точка px,py принадлежит прямой line 2')
	else
		print('симметричная точка px,py не принадлежит прямой line 2')
	end
	--проверяем одинаковы ли отрезки
	if ((x-x0)^2+(y-y0)^2)^0.5 == ((px-x0)^2+(py-y0)^2)^0.5 then
		print('длины отрезков одинаковы, координаты px,py верны')
	else
		print('длины отрезков не равны, координаты px,py не верны')
	end
	return px,py
end
print(SymmetricalPointAboutLine(-1,1,3,4,-12))
второй способ - отзеркалить спец формулами
источник
что-то не смог найти функц, наверн что то не не понял правильно

Найти прямую a,b,c
Перпендикулярная прямая
проходящая прямая e1 через точку M1(x1; y1) и перпендикулярная e2. Найти уравнение прямой e1
Уравнение перпендикулярной прямой
Прямая, проходящая через точку M1(x1; y1) и перпендикулярная прямой y=ax+b, представляется уравнением
y–y1=-1/a(x-x1) (1)

Альтернативная формула
Прямая, проходящая через точку M1(x1; y1) и перпендикулярная прямой Ax+By+C=0, представляется уравнением
A(y-y1)-B(x-x1)=0 (2)
примеры
Пример 1.
Составить уравнение прямой, проходящей через точку (2; -1) и перпендикулярной 4x-9y=3.
Решение. Данную прямую можно представить уравнением y = 4/9x – 1/3 (a = 4/9). Уравнение искомой прямой есть y+1 = -9/4(x-2), т.е. 9x+4y-14=0.
Пример №2. Решая пример 1 (A=4, B=-9) по формуле (2), найдем 4(y+1)+9(x-2)=0, т.е. 9x+4y-14=0.
Пример №3. Составить уравнение прямой, проходящей через точку (-3, -2) перпендикулярно прямой 2y+1=0.
Решение. Здесь A=0, B=2. Формула (2) дает -2(x+3)=0, т.е. x+3=0. Формула (1) неприменима, так как a=0.
способ решение задач. Найти перпендикулярную линию
Дано уравнение прямой и координаты точки. Выведите коэффициенты уравнения прямой, перпендикулярной данной прямой и проходящей через данную точку.
Ввод
0 1 -1
0 0
Отает: 1 0 0
через вектор нормали (подробный код)
--наименьший общий делитель между a,b gcd>0
function gcd(a, b)
	return b==0 and a or gcd(b,a%b)
end
--наименьший общий делитель между a,b,c
function nod(a, b, c)
	return gcd(gcd(a,b),c)
end

function EquationIntCoefficients(Px,Py,Qx,Qy)
	--находим коэ-ты уравнения
	local A,B = Py-Qy, Qx-Px
	local C = -A*Px - B*Py
	--далее нормируем коэ-ты
	
	--находим наибольший общий делитель 3 чисел
	local Z = nod(A,B,C)
	
	--коэф-ты делить на НОД
	A,B,C=A/Z,B/Z,C/Z
	
	--произведем нормировку знака
	if A<0 or (A==0 and B<0) then
		return -A,-B,-C
	end
	return A,B,C
end

--вектор нормали (перпендикулярный)
function NormalVectorLine(a,b,c)
	return a,b
end

function PerpendicularLine(x1,y1,a,b,c)

	--снимаем вектор нормали из ax+by+c=0
	local x2,y2=NormalVectorLine(a,b,c)
	
	--уравнение составим по точке x1,y1 и направляющему вектору x2,y2
	
	--уравнение перпендикулярной линии ax1+by1+c1=0 
	local a1,b1,c1 = EquationIntCoefficients(x2,y2,x1,y1)
	
    --проверка, что линия перпендикулярна
	if a1*(x1-x2) + b1*(y1-y2)==0 then 
	    print("перпедикулярны "..a1*(x1-x2) + b1*(y1-y2))
	else
	    print("не перпедикулярны "..a1*(x1-x2) + b1*(y1-y2))
	end
	
	return a1,b1,c1
end

print(PerpendicularLine(2,3,2,1,-3))
print(PerpendicularLine(2,1,9,4,-14))
print(PerpendicularLine(0,0,0,1,-1))
через вектор нормали (упрощенный)
--вектор нормали (перпендикулярный)
function NormalVectorLine(a,b,c)
	return a,b
end

function PerpendicularLine(x1,y1,a,b,c)

	--снимаем вектор нормали из ax+by+c=0
	local x2,y2=NormalVectorLine(a,b,c)
	
	--уравнение составим по точке x1,y1 и направляющему вектору x2,y2
	
	--уравнение перпендикулярной линии ax1+by1+c1=0 
	local a1,b1,c1 = (y2-y1),(x1-x2),a*(y2-y1)+b*(x2-x1)
	
    --проверка, что линия перпендикулярна
	local p = a1*(x2-x1) + b1*(y2-y1)
	if p==0 then 
	    print("перпедикулярны "..p)
	else
	    print("не перпедикулярны "..p)
	end
	
	return a1,b1,c1
end

print(PerpendicularLine(2,3,2,1,-3))
print(PerpendicularLine(2,1,9,4,-14))
print(PerpendicularLine(0,0,0,1,-1))
через угловой коэ-т (не рабочий вариант)
ax + by + c = 0 имеет беконечное множество разных a, b и с.
Уравнение прямой:
a/b*x + y + c/b = 0
y = - a/b * x - c
function PerpendicularLine(x,y,a,b,c)
	local A,B
	if b== 0 then
		A=0
		B=0
	else
		A=a/b*x
		B=-a/b * x - c
	end
	return A,B,c
end
print(PerpendicularLine(0,0,0,1,-1))
Или уравнение нужной прямой такое:
y = b/a * x - c
  • b/a * x + y + c = 0
function PerpendicularLine(x,y,a,b,c)
	local A,B
	if b== 0 then
		A=0
		B=-c
	else
		A=a/b*x
		B=-a/b * x - c
	end
	return A,B,c
end
print(PerpendicularLine(0,0,0,1,-1))
Параллельная прямая
Найти уравнение параллельной прямой
Прямая e1, проходящая через точку K(x0; y0) и параллельная прямая e2 прямой e1 находится по формуле.
Прямая, проходящая через точку K(x0; y0) и параллельная прямой y = kx + a находится по формуле:
y - y0 = k(x - x0) (1)
где k - угловой коэффициент прямой.
Альтернативная формула:
Прямая, проходящая через точку M1(x1; y1) и параллельная прямой Ax+By+C=0, представляется уравнением
A(x-x1)+B(y-y1)=0. (2)
Пример №1.
Составить уравнение прямой, проходящей через точку M0(-2,1) и при этом:
а) параллельно прямой 2x+3y -7 = 0;
б) перпендикулярно прямой 2x+3y -7 = 0.
Решение. Представим уравнение с угловым коэффициентом в виде y = kx + a. Для этого перенесем все значения кроме y в правую часть: 3y = -2x + 7. Затем разделим правую часть на коэффициент 3. Получим: y = -2/3x + 7/3
Найдем уравнение NK, проходящее через точку K(-2;1), параллельно прямой y = -2/3x + 7/3
Подставляя x0 = -2, k = -2/3, y0 = 1 получим:
y-1 = -2/3(x-(-2))
или
y = -2/3x - 1/3 или
3y + 2x +1 = 0
Пример №2. Написать уравнение прямой, параллельной прямой 2x + 5y = 0 и образующей вместе с осями координат треугольник, площадь которого равна 5.
Решение. Так как прямые параллельны, то уравнение искомой прямой 2x + 5y + C = 0. Площадь прямоугольного треугольника S=1/2 ab, где a и b его катеты. Найдем точки пересечения искомой прямой с осями координат:
2x+5y+c=0
при x=0 => 5y+c=0 => y=-c/5
при y=0 => 2x+c=0 => x=-c/2
Итак, A(-C/2,0), B(0,-C/5). Подставим в формулу для площади:
S=1/2 ab => 5 = 1/2 (-c/5 * -c/2) => c=±10
Получаем два решения: 2x + 5y + 10 = 0 и 2x + 5y – 10 = 0.
Пример №3. Составить уравнение прямой, проходящей через точку (-2; 5) и параллельной прямой 5x-7y-4=0.
Решение. Данную прямую можно представить уравнением y = 5/7x – 4/7 (здесь a = 5/7). Уравнение искомой прямой есть y – 5 = 5/7(x – (-2)), т.е. 7(y-5)=5(x+2) или 5x-7y+45=0.
Пример №4. Решив пример 3 (A=5, B=-7) по формуле (2), найдем 5(x+2)-7(y-5)=0.
Пример №5. Составить уравнение прямой, проходящей через точку (-2;5) и параллельной прямой 7x+10=0.
Решение. Здесь A=7, B=0. Формула (2) дает 7(x+2)=0, т.е. x+2=0. Формула (1) неприменима, так как данное уравнение нельзя разрешить относительно y (данная прямая параллельна оси ординат).
пример. Найти уравнение прямой e2, параллельной данной прямой e1 и находящейся от нее на заданном расстоянии r
Даны четыре числа: коэффициенты нормального уравнения прямой и величина d.
Программа должна вывести три числа: коэффициенты нормального уравнения любой из прямых, паралелльных данной, и лежащих от нее на расстоянии d.
Ввод
0 -1 1
1
Ответ: 0 -1 2
1.4 Уравнение прямой, параллельной данной и находящейся от нее на заданном расстоянии r.
Очевидно, что искомых прямых две. Вектор нормали к исходной прямой оторгонален к каждой из параллельных прямых. Значит, коэффициенты a и b при x и y в уравнении (4) для параллельных прямых можно взять такими же как и у исходной прямой.
Напомню формулу
ax+by+c=0 (4)
где a = y2-y1, b=x1-x2, c=x1*(y1-y2) + y1*(x2-x1)
Остается подобрать значение для третьего из коэффициентов. Обозначим его для одной прямой c1, для второй c2. Как было выше показано, для определения этих коэффициентов достаточно знать хотя бы по одной точке из кажой прямой.
Возьмем произвольную точку P(x0,y0) на исходной прямой (если прямая задана была не двумя точками, то точку можно найти по рецепту, предложенную в конце 1.2).
(n,P0P)=a*(x-x0)+b*(y-y0)=0 (6)
Проведем через нее прямую, перпендикулярной данной прямой.
На параллельной же прямой будет искать точку M (x1,y1) ее пересечения с этим перпендикуляром.
Нам известен один ветор нормали n=(a,b). Вектор PM коллинеарен ему, а его длина равна r. Для определенности будем считать, что как и на рисунке, нормаль лежит по ту же сторону от прямой, что и точка M.
Тогда PM = n *r / sqrt(a^2 + b^2).
Значит, координаты точки M равны
x1=x0+a*r / sqrt(a^2 + b^2)
y1=y0+b*r / sqrt(a^2 + b^2)
Подставляем их в уравнение (6), получаем
c1=-ax0 -by0 -r*sqrt(a^2 + b^2)
Уравнение одной из прямой получено. В качестве вектора нормали для другой прямой можно использовать вектор PM.
c2=-ax0 -by0 +r*sqrt(a^2 + b^2)
Прямая, параллельная данной и удаленная на расстояние r
Пусть дана прямая ax + by + c = 0. Если изменять значение коэффициента c, зафиксировав при этом значения a и b, то мы получим семейство параллельных прямых. Как получить из этого семейства прямую, параллельную исходной и удаленной от нее на заданное расстояние r?
Вектор нормали к этой прямой будет иметь вид (a, b). Длина этого вектора
d = math.sqrt(a^2 + b^2)
Поделив вектор на его длину, получим вектор единичной длины
( x=a/d, y=b/d ) единичной длины.
Умножив его на r, получим вектор ( x=a*r/d, y=b*r/d ). Этот вектор будет нормальным к исходной прямой и его длина равна d. Искомая прямая получается из исходной сдвигом на этот вектор.
Таким образом, если точка (x, y) принадлежала исходной прямой, то точка (x′, y′), где
x′ = x + ar/d,
y′ = y + br/d
принадлежит искомой прямой.
Запишем уравнение ax + by + c = 0 и подставим в него
x = x′ − ar/d,
y = y′ − br/d,
получим уравнение:
ax′−(a^2 *r)/d + by′-(b^2 *r)/d + c = 0
или
ax′ + by′ + c − rd = 0.
Уравнение второй прямой, удаленной на расстояние d от исходной, но в направлении, противоположном нормали, имеет вид:
ax′ + by′ + c + rd = 0.
function FindParallelLine(a,b,c,r)
	--находим произвольную точку
	local x0,y0=1,1
	local x=x0+a*r / math.sqrt(a^2 + b^2)
	local y=y0+b*r / math.sqrt(a^2 + b^2)
	
	if a~=0 then
    	return a,b,-a*x0 -b*y0 -r*math.sqrt(a^2 + b^2)
    else
    	return a,b,-a*x0 -b*y0 +r*math.sqrt(a^2 + b^2)
    end
end
print(FindParallelLine(0,-1,1,1))
Биссектриса угла
Даны координаты трех точек O, A, B. Постройте уравнение прямой, являющейся биссектрисой угла ∠AOB.
Ввод
1 1
1 0
0 1
-1.0 1.0 0.0
Биссектри́са (от лат. bi- «двойное», и sectio «разрезание») угла — луч, исходящий из вершины угла и делящий этот угол на два равных угла.
конспект
Пусть векторы P0P1 (x1,x1), P0P2 (x2,x2) приложены к точке P0 (x0,y0). Найдем уравнение биссектрисы угла P1P0P2. Если разделим каждый из векторов P0P1, P0P2 на его длину, получив при этом векторы единичной длины, то вектор их суммы будет лежать на биссектрисе угла между ними.
Координаты этого единичного вектора
ex = (x1 / math.sqrt(x1^2+y1^2) ) + (x2 / math.sqrt(x2^2+y2^2))
ey = (y1 / math.sqrt(x1^2+y1^2) ) + (y2 / math.sqrt(x2^2+y2^2))
Из условия его коллинеарности вектору P0P, где P(x,y) - произвольная точка по искомой прямой, то получаем уравнение биссектрисы
ey*(x-x0) - ex*(y-y0)=0 (9)
При необходимости из (9) несложно получить коэффициенты a,b,c для записи уравнения в найденной прямой в виде (4)
ax+by+c=0
где a=y-y0, b=x0-x,
c=ex*(y0-y)+ey*(x-x0)
пример
Пример.
Написать уравнения биссектрис углов, образованного прямыми 4x-3y-10=0 и 9x-12y-7=0.
Решение:
В формулу уравнения биссектрис подставляем данные прямых:
(4x-3y-10) / math.sqrt(4^2 + (-3)^2) = ±(9x-12y-7)/math.sqrt(9^2 + (-12)^2 )
(4x-3y-10)/5 = ±(9x-12y-7)/15
(12x-9y-30) = ±(9x-12y-7)
[1)
12x-9y-30 = 9x-12y-7
3x+3y-23 = 0
[2)
12x-9y-30 = -9x+12y+7
21x-21y-37=0
Ответ: 3x+3y-23=0; 21x-21y-37=0.
выделю несколько решении:
собственный (более точный)
function EquationCoefficients(Px,Py,Qx,Qy)
	local A,B = Qy-Py, Px-Qx
	C = -(A*Px + B*Py)
	return A,B,C
end

function WhereTwoPointsLine(x1,y1,x2,y2,a,b,c)
	return x1*b + y1*a>=0 and x2*b + y2*a>=0
end

function BissectorAngleInTriangle(x0,y0,x1,y1,x2,y2)
	--составить уравнение прямой e1
	local a1,b1,c1=EquationCoefficients(x0,y0,x1,y1)
	--составить уравнение прямой e2
	local a2,b2,c2=EquationCoefficients(x0,y0,x2,y2)
	
	
	local p1,p2=(a1^2+b1^2)^0.5,(a2^2+b2^2)^0.5
	
	a1,b1,c1 = a1*p2,b1*p2,c1*p2
	a2,b2,c2 = a2*p1,b2*p1,c2*p1
	
	--получаем две биссектриссы
	local a3,b3,c3=a1+a2,b1+b2,c1+c2
	local a4,b4,c4=a1-a2,b1-b2,c1-c2
	
	--найти среди них внутреннюю биссектрису
	if not WhereTwoPointsLine(x1,y1,x2,y2,a3,b3,c3) then
	    return a3,b3,c3
	else
	    return a4,b4,c4
	end
	return false
	
end

print(BissectorAngleInTriangle(1,1,1,0,0,1)) -- Ответ: -1,1,0
print(BissectorAngleInTriangle(-5,4,7,-1,3,10)) --Ответ: 1,-8,37
Если нужно привести в соответствующий вид уравнение, то надо использовать другую функцию вместо EquationCoefficients на EquationIntCoefficients, которая нормирует коэ-ты и знаки. EquationCoefficients просто преобразует коэ-ты, но ничего не нормирует.
пример:
8x -64y + 296 =0 /8 -число 8 это НОД
x -8y +37=0 -так нормируют коэ-ты
или
-3x +y +1 = 0 /-1 --надо знак нормировать, для удобства чтения
3x -y -1 = 0
--наименьший общий делитель между a,b gcd>0
function gcd(a, b)
	return b==0 and a or gcd(b,a%b)
end
--наименьший общий делитель между a,b,c
function nod(a, b, c)
	return gcd(gcd(a,b),c)
end

function EquationIntCoefficients(Px,Py,Qx,Qy)
	--находим коэ-ты уравнения
	local A,B = Py-Qy, Qx-Px
	local C = -A*Px - B*Py
	--далее нормируем коэ-ты
	
	--находим наибольший общий делитель 3 чисел
	local Z = nod(A,B,C)
	
	--коэф-ты делить на НОД
	A,B,C=A/Z,B/Z,C/Z
	
	--произведем нормировку знака
	if A<0 or (A==0 and B<0) then
		return -A,-B,-C
	end
	return A,B,C
end
второй через законспектированный единичный вектор (не уверен в правильности)
function EquationCoefficients(Px,Py,Qx,Qy)
	local A,B = Qy-Py, Px-Qx
	C = -(A*Px + B*Py)
	return A,B,C
end
function WhereTwoPointsLine(x1,y1,x2,y2,a,b,c)
	return x1*b + y1*a>=0 and x2*b + y2*a>=0
end

--биссектрисса угла. может выходить с погрешностями, не уверен в правильности
function bissector(x0,y0,x1,y1,x2,y2)
	--составить уравнение P0P1
	local a1,b1,c1=EquationCoefficients(x0,y0,x1,y1)
	--составить уравнение P0P2
	local a2,b2,c2=EquationCoefficients(x0,y0,x2,y2)
    --параметр единичного вектора
    local p = math.abs(a1)/(a1^2+b1^2)^0.5 + math.abs(a2)/(a2^2+b2^2)^0.5

	--находим две биссектриссы
    local a3,b3,c3=(a1+a2)*p,(b1+b2)*p,(c1+c2)*p
	local a4,b4,c4=(a1-a2)*p,(b1-b2)*p,(c1-c2)*p

	if not WhereTwoPointsLine(x1,y1,x2,y2,a3,b3,c3) then
		return a3,b3,c3
	else
		return a4,b4,c4
	end
		
	return false
end

print(bissector(1,1,1,0,0,1)) --1	1	0.0
print(bissector(-5,4,7,-1,3,10)) --1 -8 37
третий вариант
код C++
// Прямая
class line
{
public: 
    double a, b, c;
    // Создание прямой ax + by + c = 0
    line(double _a = 0, double _b = 0, double _c = 0) 
    {
        a = _a;
        b = _b;
        c = _c;
    }
};

// уравнение прямой, проходящей через две точки
line toline (point p1, point p2)
{
    double a = p2.y - p1.y;
    double b = p1.x - p2.x;

    return line(a, b, - a * p1.x - b * p1.y);
}

// отрезки :: деление отрезка в заданном отношении
point part_segment (point p1, point p2, double m, double n)
{
    point t;
    t.x = (p1.x * n + p2.x * m) / (m + n);
    t.y = (p1.y * n + p2.y * m) / (m + n);
    return t;
}

// расстояние между двумя точками
double dist(point a, point b)
{
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

line bisector_line (point a, point b, point c)
{
    double ab = dist (a, b);
    double bc = dist (b, c);
    point tab = part_segment (b, a, bc, ab);
    point tbc = part_segment (b, c, ab, bc);
    point p = part_segment (tab, tbc, 1, 1);
    return toline (b, p);
}
lua код
-- уравнение прямой, проходящей через две точки
function toline (p1, p2)
    local a = p2.y - p1.y;
    local b = p1.x - p2.x;

    return a, b, - a * p1.x - b * p1.y
end

-- отрезки :: деление отрезка в заданном отношении
function part_segment (p1, p2, m, n)

    local t = {}
    t.x = (p1.x * n + p2.x * m) / (m + n);
    t.y = (p1.y * n + p2.y * m) / (m + n);
    return t;
end

-- расстояние между двумя точками
function dist(a, b)
    return math.sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
end

function bisector_line (a, b, c)
    local ab = dist (a, b);
    local bc = dist (b, c);
    local tab = part_segment (b, a, bc, ab);
    local tbc = part_segment (b, c, ab, bc);
    local p = part_segment (tab, tbc, 1, 1);
    return toline (b, p);
end


--координаты AOB, а не OAB
print(bisector_line ({x=1,y=0}, {x=1,y=1}, {x=0,y=1})) -- Печатает: -0.25	0.25	0.0
lua код (с нормированием в целое коэф-тов)
--наименьший общий делитель между a,b gcd>0
function gcd(a, b)
	return b==0 and a or gcd(b,a%b)
end
--наименьший общий делитель между a,b,c
function nod(a, b, c)
	return gcd(gcd(a,b),c)
end

-- уравнение прямой, проходящей через две точки
function toline (p1, p2)
    local a = p2.y - p1.y;
    local b = p1.x - p2.x;

    return a, b, - a * p1.x - b * p1.y
end

-- отрезки :: деление отрезка в заданном отношении
function part_segment (p1, p2, m, n)

    local t = {}
    t.x = (p1.x * n + p2.x * m) / (m + n);
    t.y = (p1.y * n + p2.y * m) / (m + n);
    return t;
end

-- расстояние между двумя точками
function dist(a, b)
    return math.sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
end

function bisector_line (a, b, c)
    local ab = dist (a, b);
    local bc = dist (b, c);
    local tab = part_segment (b, a, bc, ab);
    local tbc = part_segment (b, c, ab, bc);
    local p = part_segment (tab, tbc, 1, 1);
    return toline (b, p);
end

--координаты AOB, а не OAB
local a,b,c = bisector_line ({x=1,y=0}, {x=1,y=1}, {x=0,y=1}) -- Печатает: -0.25	0.25	0.0
--находим наибольший общий делитель 3 чисел
local Z = nod(a,b,c)
--коэф-ты делить на НОД
a,b,c=a/Z,b/Z,c/Z
--произведем нормировку знака (если не делать нормировку, то получаем тот результат, который указан в задании -1,1,0)
if a<0 or (a==0 and b<0) then
	return -a,-b,-c
end
print(a,b,c) --Печатает 1,-1,0
касательная прямая к окружности
Касательная к окружности - это прямая пересекающая окружность в двух точках
Окружность может представлена в виде нескольких исходных данных
  1. В виде координат центра окружности (x0,y0) и ее радиуса R
(x-x0)^2 + (y-y0)^2 = R^2
  1. В виде общего уравнения:
x^2+y^2 + Ax +By + C = 0
A = -2*x0
B= -2*y0
C = x0^2 + y0^2 - R^2
ПРОВЕРКИ ПРИНАДЛЕЖНОСТИ ОДНОГО ГЕОМЕТРИЧЕСКОГО ОБЪЕКТА К ДРУГОМУ
Принадлежность точки прямой
вариант 1 (даны 2 точки, определяющие направление прямой)
--проверяем на коллинеарность, и что точка лежит на линии
function PointOnLine(x,y,x1,y1,x2,y2)
	return(x - x1) * (y2 - y1) - (y - y1) * (x2 - x1)==0
end
print(PointOnLine(0,0,0,1,0,2))
print(PointOnLine(0,0,1,1,1,2))
вариант 2 (даны a,b,c коэ-ты уравнения прямой ax+by+c=0)
Даны координаты точки и уравнение прямой. Определите, принадлежит ли точка прямой, выведите YES или NO.
Ввод
3 7
-2 1 -1
Ответ YES
EPS = 1E-9;
function pointOnLine(x,y,a,b,c)
	return a*x + b*y + c <= EPS
end
11: Принадлежность точки лучу
Программа получает на вход шесть чисел: координаты точки (1,6) и координаты начала (3,7) и конца вектора (5,8). Проверьте, принадлежит ли данная точка лучу, задаваемому данным вектором.
Программа должна вывести YES, если точка принадлежит лучу, или NO в противном случае.
Ответ: при таких данных программа вернет NO
Решение:
Давайте вспомним, что такое луч: луч — это прямая, ограниченная точкой с одной стороны, а с другой стороны бесконечная. То есть луч задается некоторой начальной точкой и любой точкой лежащей на нем.
вариант 1. мой собственный способ из предыдущих уроков
--если три вектора-точки лежат на одной прямой
function IsThreeVectorsCollinear(x,y,x1,y1,x2,y2)
	return (x-x1)*(y2-y1)-(y-y1)*(x2-x1)==0 --8 опер
end
--если три вектора сонаправлены dx1*dx2 + dy1*dy2 > 0
--эта функция использует для принадлежности точки M(x,y) лучу P1(x1,y1),P2(x2,y2)
--проверка идет между P1M и P1P2
function IsThreVectorsCodirectional(x,y,x1,y1,x2,y2)
	return (x-x1)*(x2-x1) + (y-y1)*(y2-y1) > 0 --8 опер
end

--точка принадлежит лучу (соблюдает 2 условия)
--векторы коллинеарны - лежат на одной прямой
--скаляр векторов [P1M,P1P2]  > 0 - сонаправлены. луч имеет начало x1,y1, поэтому от этой точки строится уравнение
function IsPointOnBeam(x,y,x1,y1,x2,y2)
	return IsThreeVectorsCollinear(x,y,x1,y1,x2,y2) and IsThreVectorsCodirectional(x,y,x1,y1,x2,y2) --8+8+3=19 опер
end

print(IsPointOnBeam(1,6,3,7,5,8)) -- вернет false
print(IsPointOnBeam(3,3,1,2,5,4)) -- вернет true
вариант 2 - самый краткий
Пусть O(x, y) – координаты точки, A(x1, y1) – координаты вершины луча, B(x2, y2) – координаты точки, лежащей на луче. Сначала следует проверить, лежит ли точка O на прямой AB:
(x – x1) * (y2 – y1) = (x2 – x1) * (y – y1)
Точки O и B должны находиться по одну сторону от вершины луча A. Это условие следует записать как для координаты x, так и для y:
(x-x1)*(x2-x1)>0 и (y-y1)*(y2-y1)>0
Реализуем проверку принадлежности точки лучу согласно выше приведенным условиям
function IsPointOnBeam2(x,y,x1,y1,x2,y2)
	return ((x-x1)*(y2-y1) == (x2-x1)*(y-y1)) and ((x-x1) * (x2-x1) >= 0) and ((y-y1)*(y2-y1) >= 0)
end

print(IsPointOnBeam2(1,6,3,7,5,8)) --вернет false
принадлежность точки отрезку
способов миллион, приведу несколько способов:
сравнение длин отрезков
function IsPointInSegment(x,y,x1,y1,x2,y2)
	return((x1-x)^2+(y1-y)^2)^0.5 + ((x2-x)^2+(y2-y)^2)^0.5 == ((x2-x1)^2+(y2-y1)^2)^0.5 
end

print(IsPointInSegment(15,0,100,0,200,0)) -- false
print(IsPointInSegment(0,150,0,100,0,200)) -- true
точка в ректе (прямоугольнике)
юзал для нахождения точки внутри отрезка
этот метод не совсем точный. Точка может не лежать на отрезке. Использовал это для проверки, что на линии точка находится внутри отрезка. Для точности предлагаю использовать и вторую проверку PointOnLine
function PointInRect(x,y,x1,y1,x2,y2)
    local minx,miny=math.min(x1,x2),math.min(y1,y2)
    local maxx,maxy=math.max(x1,x2),math.max(y1,y2)
    
    return (minx<=x and x<=maxx) and (miny<=y and y<=maxy)
end

print(PointInRect(15,0,100,0,200,0)) -- false
print(PointInRect(0,150,0,100,0,200)) -- true
3 способ
-- Vec2 is a simple x/y struct - it could very well be named Point for this use
function isBetween(a,b,c)
    local larger,smaller
	--return if c is between a and b
	if(a >= b)then larger=a else larger=b end
	if(a ~= larger)then smaller=a else smaller=b end
    return c <= larger and c >= smaller;
end

function pointOnLine(x,y,x1,y1,x2,y2)
    if(x2-x1 == 0)then return isBetween(y1,y2,y); end --vertical line
    if(y2-y1 == 0)then return isBetween(x1,x2,x); end --horizontal line

    local Ax = (x - x1) / (x2 - x1);
    local Ay = (y - y1) / (y2 - y1);

    -- We want Ax == Ay, so check if the difference is very small (floating
    -- point comparison is fun!)
    return math.abs(Ax - Ay) < 0.000001 and Ax >= 0.0 and Ax <= 1.0;
end

print(pointOnLine(15,0,100,0,200,0)) -- false
print(pointOnLine(0,150,0,100,0,200)) -- true
мой собственный вариант (мой старый вариант)
Программа получает на вход шесть чисел: координаты точки (3,3) и координаты концов отрезка (1,2),(5,4). Проверьте, принадлежит ли данная точка данному отрезку.
Программа должна вывести YES, если точка принадлежит отрезку, или NO в противном случае.
Ответ: при таких данных программа вернет YES
Пусть точки P1(x1, y1), P2(x2, y2) концы заданного отрезка. Опять-таки необходимым условием принадлежности точки отрезку является ее принадлежность прямой проходящей через P1, P2. Далее нам нужно определить лежит ли точка между точками P1 и P2, для этого нам на помощь приходит скалярное произведение векторов только на этот раз других: (MP1, MP2). Если оно меньше либо равно нуля, то точка лежит на отрезке, иначе вне отрезка. Почему так? Посмотрим на рисунок.
--если три вектора-точки лежат на одной прямой (коллинеарны)
function IsThreeVectorsCollinear(x,y,x1,y1,x2,y2)
	return (x-x1)*(y2-y1)-(y-y1)*(x2-x1)==0 --8 опер
end

--если три вектора сонаправлены dx1*dx2 + dy1*dy2 > 0
--эта функция использует для принадлежности точки M(x,y) отрезку P1(x1,y1),P2(x2,y2)
--проверка идет между MP1 и MP2
function IsThreVectorsCodirectional2(x,y,x1,y1,x2,y2)
	return (x-x1)*(x-x2) + (y-y1)*(y-y2) < 0 --8 опер
end

--точка принадлежит отрезку (соблюдает 2 условия)
--векторы коллинеарны - лежат на одной прямой
--скаляр векторов [MP1,MP2]  > 0 - сонаправлены. луч имеет начало x1,y1, поэтому от этой точки строится уравнение
function IsPointOnSegment(x,y,x1,y1,x2,y2)
	return IsThreeVectorsCollinear(x,y,x1,y1,x2,y2) and IsThreVectorsCodirectional2(x,y,x1,y1,x2,y2)
end

print(IsPointOnSegment(1,6,3,7,5,8)) -- вернет false
print(IsPointOnSegment(3,3,1,2,5,4)) -- вернет true
угол лежит между двумя углами
Примечание: угол между двумя углами должен приведен в градусы math.deg(angle), а также должен быть положительным math.abs(angle). По факту в модуль lua отбрасывает отриц знаки, но в некоторых вариантах (в 2 способе) полярный угол atan2 возвращает минус, и при вычислении неверный результат выдает.
Следует отметить, что здесь ориентацию угла по знаку не принимают во внимание, и рассматривают «просто угол», который >=0
первый способ (надежный)
--угол лежит между двумя углами
function IsAngleBetweenAngles(angle,angle1,angle2)
	N = angle%360 --normalize angles to be 1-360 degrees
	a = angle1%360
	b = angle2%360

	if (a < b)then
		return a <= N and N <= b;
	else
		return a <= N or N <= b;
	end
end

print(IsAngleBetweenAngles(150, 80, 320)) --=> true
print(IsAngleBetweenAngles(30, 80, 320)) --=> false
print(IsAngleBetweenAngles(340, 80, 320)) --=> false
print(IsAngleBetweenAngles(140, 0, 160)) --=> true
print(IsAngleBetweenAngles(180, 0, 160)) --=> false
print(IsAngleBetweenAngles(1, 0, 360)) --=> true
второй способ (не очень)
function AngleBetween(a,b)
    local a = (math.modf(b)-math.modf(a)) % 360;
    if a==0 then
        return 360
    end
    return a
end
function IsInsideRange(testAngle,startAngle,endAngle)
    local a1 = math.abs(AngleBetween(startAngle, testAngle));
    local a2 = math.abs(AngleBetween(testAngle, endAngle));
    local a3 = math.abs(AngleBetween(startAngle, endAngle));
    print(a1,a2,a3)
    return a1 + a2 == a3;
end

print(IsInsideRange(150, 80, 320)) --=> true
print(IsInsideRange(30, 80, 320)) --=> false
print(IsInsideRange(340, 80, 320)) --=> false
print(IsInsideRange(140, 0, 160)) --=> true
print(IsInsideRange(180, 0, 160)) --=> false
print(IsInsideRange(1, 0, 360)) --=> true
угол принадлежит минимальному промежутку между углами
условие работает, если промежуток между angle1 и angle2 не слишком большой < 180. Иначе, просто вернет false.
тут тоже код оперируется в градусах, тк все вычисления происходят из того, что круг равен 360.
первый вариант (взят из хгм)
--определяет лежит ли угол между двумя углами
function IsAngleBetweenAngles(angle,angle1,angle2)
    angle = angle%360
    angle1 = angle1%360
    angle2 = angle2%360
    if (angle1>angle2) then
        angle1,angle2 = angle2,angle1
    end
    if (angle2-angle1) > (angle1 - (angle2-360)) then
        angle2 = angle2 - 360
        if angle > 180 then
            angle = angle-360
        end
        return angle >= angle2 and angle <= angle1
    end
    return (angle >= angle1) and (angle <= angle2)
end
второй вариант
-- минимальный промежуток угла
function is_angle_between(target,angle1,angle2) 
	--make the angle from angle1 to angle2 to be <= 180 degrees
	local rAngle = ((angle2 - angle1) % 360 + 360) % 360;
	if (rAngle >= 180)then
		angle1,angle2=angle2,angle1
    end
	-- check if it passes through zero
	if (angle1 <= angle2)then
		return target >= angle1 and target <= angle2;
	else
		return target >= angle1 or target <= angle2;
	end
end

print(is_angle_between(150, 80, 320)) --=> false
print(is_angle_between(30, 80, 320)) --=> true
print(is_angle_between(340, 80, 320)) --=> true
print(is_angle_between(140, 0, 160)) --=> true
print(is_angle_between(180, 0, 160)) --=> false
print(is_angle_between(1, 0, 360)) --=> true
Принадлежит ли точка углу
Дан угол AOB (O-вершина угла, A и B - точки на сторонах) и точка P. Определите, принадлежит ли точка P углу AOB (включая его сторонв: лучи OA и OB).
Входные данные
Программа получает на вход координаты точек A, O, B, P. Все координаты - целые, не превосходят 100 по модулю. Точки A, O, B не лежат на одной прямой.
Выходные данные
0,1
0,0
1,0
1,1
ответ yes
1,0
0,0
0,1
-1,-1
ответ no
Программа должна вывести слово YES или NO.
function IsAngleBetweenAngles(angle,angle1,angle2)
	N = angle%360 --normalize angles to be 1-360 degrees
	a = angle1%360
	b = angle2%360

	if (a < b)then
		return a <= N and N <= b;
	else
		return a <= N or N <= b;
	end
end

--P (x,y), O (cx,cy) - вершина угла, A и B - стороны угла AOB
function IsPointBetweenTwoAngle(cx,cy,x,y,x1,y1,x2,y2)
	local a=math.abs(math.deg(math.atan2(y-cy,x-cx)))
	local a1=math.abs(math.deg(math.atan2(y1-cy,x1-cx)))
	local a2=math.abs(math.deg(math.atan2(y2-cy,x2-cx)))
	print(a,a1,a2)
	return IsAngleBetweenAngles(a,a1,a2)
end

print(IsPointBetweenTwoAngle(0,1,0,0,1,0,1,1))
print(IsPointBetweenTwoAngle(1,0,0,0,0,1,-1,-1))
`
ОЖИДАНИЕ РЕКЛАМЫ...
2
27
2 года назад
Отредактирован MpW
2
К сожалению, завершил. Не хватает места, не осталось тестов. И пр.
тесты с приложенным конспектом
учебник хороший по алгебре
полезная библиотека
ну и три оставшиеся задачи, которые не влезли
задача про Точки касания
Даны пять чисел: координаты центра окружности, ее радиус (в первой строке), координаты точки (во второй строке).
Выведите одно число K, равное количеству точек пересечения всевозможных касательных к окружности, проходящих через данную точку. Далее в K строках координаты самих точек пересечения касательных с окружностью.
Ввод
1 1 1
2 2
Ответ:
2 точки
1.0 2.0
2.0 1.0
Пересечение окружностей
Даны шесть чисел – координаты центров и радиусы двух окружностей окружности.
В случае если количество общих точек окружностей конечно, в первой строке вывести одно число K, равное этому количеству, далее в K строках координаты самих точек. Если указанных точек бесконечно много, вывести единственное число "3".
Ввод
2 3 1
3 2 1
Ответ:
2
3.0 3.0
2.0 2.0
решение приложено выше
Длина дуги
Даны семь чисел – координаты центра и радиус окружности (в первой строке) и действительные координаты двух точек на ней (во второй и третьей строке), с точностью до пятого знака после запятой.
Выведите одно число: длину меньшей из дуг окружности, заключенной между указанными точками.
Ввод
1 1 1
2.0 1.0
1.0 2.0
Ответ: 1.5707963267948966
остальное про многоугольник и пр в другом материале есть
Чтобы оставить комментарий, пожалуйста, войдите на сайт.