Я считаю, что есть несколько проблем с вашим кодом. Вероятно, наиболее важным является логика линии:
let y = min p1.X p2.X + dy * (x - min p1.X p2.X) / dx
Очевидно, это должно было быть что-то вроде
y = y0 + (x-x0)*dy/dx
т.е. первый термин должен быть чем-то вроде Y
, а не X
. К сожалению, с вашей логикой зацикливания это должна быть Y
точки, которая имеет меньшую X
. Это не так просто сказать. ИМХО, проще исправить цикл, используя отрицательный шаг.
Другое наивное предположение состоит в том, что вы всегда можете нарисовать линию, имеющую по y
для каждого x
. Это явно не так, когда dy > dx
. Более того, в случае вертикальной линии, когда dx
равен 0
, код не будет выполнен. Самый популярный линейный алгоритм Брезенхама требует, чтобы вы обрабатывали эти случаи как явно отличающиеся. Вот простая реализация, которая обрабатывает эти случаи:
let drawLine p1 p2 =
let dx = p2.X - p1.X
let dy = p2.Y - p1.Y
if((dx <> 0) || (dy <> 0)) then
if abs(dx) >= abs(dy) then
let step = if (p1.X < p2.X) then 1 else -1
for x in p1.X ..step.. p2.X do
let y = p1.Y + dy * (x - p1.X) / dx
Console.SetCursorPosition(x, y)
printf "."
else
let step = if (p1.Y < p2.Y) then 1 else -1
for y in p1.Y .. step .. p2.Y do
let x = p1.X + dx * (y - p1.Y) / dy
Console.SetCursorPosition(x, y)
printf "."
Что касается других вопросов, вы, вероятно, захотите ограничить позиции ваших точек какой-либо видимой областью между 0 и некоторым максимальным значением. SetCursorPosition
вызов с отрицательным значением или значением, превышающим размер буфера, приведет к сбою приложения.