Перейти к публикации
Форум - ComputerCraft
Appo

Ломанная в движении. Иллюзия 3D

Рекомендованные сообщения

Можно использовать как заставку :)

Установка:
 pastebin run U0pK04Rp

Код:


 

local size = 4 -- Больше 4 начинается мерцание некоторых линий
local x0,y0 = 160,50

local component = require("component")
local gpu = component.gpu
local term = require('term')

function line(x1,y1,x2,y2)
	x= x1
	y= y1
	for i = 1 , math.floor( ( (x2-x1 )^2+( y1-y2 )^2)^0.5) do
		gpu.set(math.floor(x),math.floor(y),'█')

		rad = math.atan2(y1-y2,x2-x1)
		x = x + math.cos(rad)
		y = y - math.sin(rad)
	end
end

local t = {}

function rnd()
	if math.random(0,1) == 0 then
		return -1
	else 
		return 1
	end
end

for i = 1, size do
	t[i] = {['x'] = math.random(1,120),['y'] = math.random(1,50),['dx'] = rnd(),['dy'] = rnd()}
end

term.clear()

while true do
	for i = 1, size do
		t[i].x = t[i].x + t[i].dx
		t[i].y = t[i].y + t[i].dy

		if t[i].x > x0 then t[i].dx = -1 end
		if t[i].y > y0 then t[i].dy = -1 end
		if t[i].x < 1 then t[i].dx = 1 end
		if t[i].y < 1 then t[i].dy = 1 end
	end
	for i = 1, size-1 do
		line(t[i].x,t[i].y,t[i+1].x,t[i+1].y)
	end
	line(t[1].x,t[1].y,t[size].x,t[size].y)
	os.sleep(0.001)
	term.clear()
end

 



p.s.
  Посоветуйте пожалуйста, как избавится от мерцание при отрисовке линий, когда их более 4. Пробывал эти же пиксели замазывать, но так только хуже, term.clear() решает.
  А так же, как реализовать пиксели в пол символа? Если не трудно, скиньте пожалуйста код где это реализовано что бы можно было понять как это работает, заранее спасибо)

Изменено пользователем Appo
  • Like 6

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А какая причина мерцания? Я не заметил.

Таблица.

Полусимвол 0x2580, набор точек 4x2 0x2802 - 0x28FF

Пример

Изменено пользователем Doob

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А какая причина мерцания? Я не заметил.

Переменную size в первой строке программы измените на большее 4, тогда начнется мерцание некоторых линий..

 

 

 

И делай, пожалуйста, выход из программы по нажатию какой либо клавиши. 

Окей, сделаю на Esc

 

-------

 

Спасибо за примеры :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А ещё к таким программам очень хорошо бы прикладывать скрины.  :)

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Годная софтинка. Пожалуй, стырю в качестве скринсейвера, если не против. Есть, правда, парочка деликатных моментов: во-первых, отрисовка линий через atan/sin/cos хоть и проста, но крайне неэффективна. Рекомендую использовать следующий код, основанный на модифицированном алгоритме Питера Ширли и предназначенный специально для низкопроизводительных машин (значительно быстрее, чем классический алгоритм Брезенхема):

local function line(x1, y1, x2, y2, color)
  local inLoopValueFrom, inLoopValueTo, outLoopValueFrom, outLoopValueTo, isReversed, inLoopValueDelta, outLoopValueDelta = x1, x2, y1, y2, false, math.abs(x2 - x1), math.abs(y2 - y1)
  if inLoopValueDelta < outLoopValueDelta then
    inLoopValueFrom, inLoopValueTo, outLoopValueFrom, outLoopValueTo, isReversed, inLoopValueDelta, outLoopValueDelta = y1, y2, x1, x2, true, outLoopValueDelta, inLoopValueDelta
  end
 
  if outLoopValueFrom > outLoopValueTo then
    outLoopValueFrom, outLoopValueTo = outLoopValueTo, outLoopValueFrom
    inLoopValueFrom, inLoopValueTo = inLoopValueTo, inLoopValueFrom
  end
 
  local outLoopValue, outLoopValueCounter, outLoopValueTriggerIncrement = outLoopValueFrom, 1, inLoopValueDelta / outLoopValueDelta
  local outLoopValueTrigger = outLoopValueTriggerIncrement
  for inLoopValue = inLoopValueFrom, inLoopValueTo, inLoopValueFrom < inLoopValueTo and 1 or -1 do
    if isReversed then
      -- setPixel(outLoopValue, inLoopValue, color)
    else
      -- setPixel(inLoopValue, outLoopValue, color)
    end
 
    outLoopValueCounter = outLoopValueCounter + 1
    if outLoopValueCounter > outLoopValueTrigger then
      outLoopValue, outLoopValueTrigger = outLoopValue + 1, outLoopValueTrigger + outLoopValueTriggerIncrement
    end
  end
end

Во-вторых, я бы использовал либу буферизации графики, чтобы не было "промигиваний", и была возможность выставлять хоть 50 линий за раз. Также она уже имеет функции растеризации отрезков, в том числе полупиксельных:
 
FLMot0V.png?1

Изменено пользователем ECS
  • Like 5

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Рекомендую использовать следующий код, основанный на модифицированном алгоритме Питера Ширли и предназначенный специально для низкопроизводительных машин (значительно быстрее, чем классический алгоритм Брезенхема):

Не нашел в интернете алгоритм Питера Ширли, да и его в целом, выскакивает какой-то музыкант) Можно узнать где вы нашли его алгоритм? Хотя бы ссылку или книгу, может у него и другие эффективные алгоритмы есть.

 

Спасибо за советы, приму к сведению и постараюсь применить их в новой версии кода :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Не нашел в интернете алгоритм Питера Ширли, да и его в целом, выскакивает какой-то музыкант) Можно узнать где вы нашли его алгоритм? Хотя бы ссылку или книгу, может у него и другие эффективные алгоритмы есть.

 

Спасибо за советы, приму к сведению и постараюсь применить их в новой версии кода :)

 

Книга "Fundamentals of Computer Graphics", хоть она и не очень: есть пара интересных алгоритмов по быстрой растеризации примитивов, но именно что лишь пара. Да и те пришлось изрядно оптимизировать, чтобы GC не грузили.

  • Like 2

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас

×