Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Разное
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 27.06.2013, 14:37
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию Перевод с Javascript на адекватный язык

Нашел на хабре пример генерации ландшафта, а он на джаваскрипте, как можно без особых замарочек перевести его например в Си или дельфи?
Мне некоторые моменты в коде дико шаблон рвут.
Код:
function ge(id) {
	return document.getElementById(id);
}

// Lazy implementation of fractal landscape generation (diamond-square algorithm)
// AUTHOR: deNULL (me@denull.ru)
// TODO: Make a nice wrapper (done), add Voronoi diagram modulation, optimize something

DiamondSquare = function(size, roughness, seed) {
	// public fields
	this.size = size;
	this.roughness = roughness;
	this.seed = (seed ? seed : Math.random());
	var opCount = 0;

	// private field
	var data = new Array();

	// public methods
	this.value = function(x, y, v) {
		x = parseInt(x);
		y = parseInt(y);
		if (typeof(v) != 'undefined')
			val(x, y, v);
		else
			return val(x, y);
	}
	this.clear = function() {
		data = new Array();
	}
	this.opCount = function(v) {
		if (typeof(v) != 'undefined')
			opCount = v;
		else
			return opCount;
	}

	// private methods
	function val(x, y, v) {
		if (typeof(v) != 'undefined')
			data[x + '_' + y] = Math.max(0.0, Math.min(1.0, v));
		else {
			if (x <= 0 || x >= size || y <= 0 || y >= size) return 0.0;

			if (data[x + '_' + y] == null) {
				opCount++;
				base = 1;
				while (((x & base) == 0) && ((y & base) == 0))
					base <<= 1;

				if (((x & base) != 0) && ((y & base) != 0))
					squareStep(x, y, base);
				else
					diamondStep(x, y, base);
			}
			return data[x + '_' + y];
		}
	}

	function randFromPair(x, y) {
		for (var i = 0; i < 80; i++) {
			var xm7 = x % 7;
			var xm13 = x % 13;
			var xm1301081 = x % 1301081;
			var ym8461 = y % 8461;
			var ym105467 = y % 105467;
			var ym105943 = y % 105943;
			//y = (i < 40 ? seed : x);
			y = x + seed;
			x += (xm7 + xm13 + xm1301081 + ym8461 + ym105467 + ym105943);
		}

		return (xm7 + xm13 + xm1301081 + ym8461 + ym105467 + ym105943) / 1520972.0;
	}

	function displace(v, blockSize, x, y) {
		return (v + (randFromPair(x, y, seed) - 0.5) * blockSize * 2 / size * roughness);
	}

	function squareStep(x, y, blockSize) {
		if (data[x + '_' + y] == null) {
			val(x, y,
				displace((val(x - blockSize, y - blockSize) +
						  val(x + blockSize, y - blockSize) +
						  val(x - blockSize, y + blockSize) +
						  val(x + blockSize, y + blockSize)) / 4, blockSize, x, y));
		}
	}
	function diamondStep(x, y, blockSize) {
		if (data[x + '_' + y] == null) {
			val(x, y,
				displace((val(x - blockSize, y) +
						  val(x + blockSize, y) +
						  val(x, y - blockSize) +
						  val(x, y + blockSize)) / 4, blockSize, x, y));
		}
	}
}

var rough, seed, waterLevel, sz, vwSz, xofs, yofs, land;

function redrawMap(id) {
	var stTime = (new Date()).getTime();
	var display = document.getElementById('map' + id);
	var stage = display.getContext('2d');
	var dispSz = display.width;
	var curSz = (id == 1 ? sz : vwSz);
	var curXOfs = (id == 1 ? 0 : xofs);
	var curYOfs = (id == 1 ? 0 : yofs);
	var scale = curSz / dispSz;
	var baseOp = 0;

	var img = stage.createImageData(dispSz, dispSz);
	land.opCount(0);

	for (var i = 0; i < dispSz; i++) {
		for (var j = 0; j < dispSz; j++) {
			baseOp++;
			var v = land.value(i * scale + curXOfs, j * scale + curYOfs);
			v *= v;

			var idx = (i + j * (dispSz)) * 4;
			if (v < waterLevel) {
				img.data[idx] = 0;
				img.data[idx + 1] = 0;
				img.data[idx + 2] = parseInt(v * 255.0) + 128;
			} else {
				img.data[idx] = parseInt(v * 255.0);
				img.data[idx + 1] = parseInt(v * 255.0);
				img.data[idx + 2] = parseInt(v * 255.0);
			}
			img.data[idx + 3] = 255;
		}
	}

	stage.putImageData(img, 0, 0);
	stage.fillStyle = 'rgba(255,255,255,0.7)';
	stage.fillRect(4, 4, 168, 36);
	stage.fillStyle = 'black';
	stage.fillText('(' + curXOfs + ', ' + curYOfs + '), ' + curSz + 'x' + curSz, 8, 15);
	stage.fillText('канва ' + dispSz + 'x' + dispSz + ', масштаб 1:' + scale, 8, 25);
    var enTime = (new Date()).getTime();
    stage.fillText('действий: ' + land.opCount() + ', ' + (enTime - stTime) + 'мс', 8, 35);
}

function updateParams() {
	sz = parseInt(ge('sz').value);
	xofs = parseInt(ge('xofs').value);
	yofs = parseInt(ge('yofs').value);
	vwSz = parseInt(ge('vwSz').value);
	var nseed = parseInt(ge('seed').value);
	var nrough = parseFloat(ge('rough').value);
	var nwaterLevel = parseFloat(ge('waterLevel').value);

	if (nseed != seed || nrough != rough || nwaterLevel != waterLevel) {
		seed = nseed;
		rough = nrough;
		waterLevel = nwaterLevel;
		land = new DiamondSquare(sz, rough, seed);
		redrawMap(1);
	}
	redrawMap(2);
}

function posHelpers() {
	var _sz = parseInt(ge('sz').value);
	var _xofs = parseInt(ge('xofs').value) / (_sz / 512);
	var _yofs = parseInt(ge('yofs').value) / (_sz / 512);
	var _vwSz = parseInt(ge('vwSz').value) / (_sz / 512);

	var wnd = ge('wnd');
	wnd.style.left = _xofs;
	wnd.style.top = _yofs;
	wnd.style.width = _vwSz;
	wnd.style.height = _vwSz;

	wnd = ge('wndNW');
	wnd.style.left = _xofs;
	wnd.style.top = _yofs;
	wnd = ge('wndNE');
	wnd.style.left = _xofs + _vwSz - 6;
	wnd.style.top = _yofs;
	wnd = ge('wndSE');
	wnd.style.left = _xofs + _vwSz - 6;
	wnd.style.top = _yofs + _vwSz - 6;
	wnd = ge('wndSW');
	wnd.style.left = _xofs;
	wnd.style.top = _yofs + _vwSz - 6;
}

var dragging = false;
var dX, dY, did;
var sx, sy, ssz;
function drag(id, event, start) {
	if (typeof(start) == 'undefined') {
		if (dragging) {
			var _sz = parseInt(ge('sz').value) / 512;
			var _xofs = sx, _yofs = sy, _vwSz = ssz;

			switch (did) {
				case 1:
					_xofs = sx + (event.x - dX);
					_yofs = sy + (event.y - dY);
					break;
				case 2:
					var dt = Math.min(event.x - dX, event.y - dY);
					_vwSz = ssz - dt;
					_xofs = sx + dt;
					_yofs = sy + dt;
					break;
				case 3:
					var dt = Math.min(- (event.x - dX), event.y - dY);
					_vwSz = ssz - dt;
					_yofs = sy + dt;
					break;
				case 4:
					_vwSz = ssz + Math.min(event.x - dX, event.y - dY);
					break;
				case 5:
					var dt = Math.min(event.x - dX, -(event.y - dY));
					_vwSz = ssz - dt;
					_xofs = sx + dt;
					break;
			}
			if (_vwSz < 0) {
				_vwSz = -_vwSz;
				_xofs -= _vwSz;
				_yofs -= _vwSz;
				did = 2 + (did % 4);
				dX = event.x;
				dY = event.y;
				sx = _xofs;
				sy = _yofs;
				ssz = _vwSz;
			}
			ge('xofs').value = parseInt(_xofs * _sz);
			ge('yofs').value = parseInt(_yofs * _sz);
			ge('vwSz').value = parseInt(_vwSz * _sz);

			posHelpers();
		}
	} else {
		dragging = start;
		if (!dragging) {
			xofs = parseInt(ge('xofs').value);
			yofs = parseInt(ge('yofs').value);
			vwSz = parseInt(ge('vwSz').value);
			redrawMap(2);
		} else {
			var _sz = parseInt(ge('sz').value) / 512;
			sx = parseInt(ge('xofs').value) / _sz;
			sy = parseInt(ge('yofs').value) / _sz;
			ssz = parseInt(ge('vwSz').value) / _sz;
			dX = event.x;
			dY = event.y;
			did = id;
		}
	}

}

function clearCache() {
	if (land) land.clear();
}

С ответом не торопитесь, может найду вменяемый пример на Си.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию

Последний раз редактировалось M.A.D.M.A.N., 27.06.2013 в 14:41.
Ответить с цитированием
Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение:
WinMon (30.06.2013)
  #2  
Старый 27.06.2013, 14:50
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Нашел реализацию на lua, там еще мозговыносней.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию

Последний раз редактировалось M.A.D.M.A.N., 27.06.2013 в 15:27.
Ответить с цитированием
Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение:
WinMon (30.06.2013)
  #3  
Старый 27.06.2013, 22:39
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

А какие моменты рвут шаблон? Попробую угадать:
var data - тип определяется тем, что туда присвоят. Т.е. надо курить тип правой части присваивания.
this.value = function(x, y, v) { ... } - предполагаю, подобие лямбды в C#, типа функция без имени.
Остальное вроде весьма C-образно.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #4  
Старый 27.06.2013, 22:53
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Вот это рвет
Код:
data[x + '_' + y] == null

Я нашел этот код на си, если и там я фигеть буду, то дерну код на асме вообще.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение:
WinMon (30.06.2013)
  #5  
Старый 27.06.2013, 22:55
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Походу это кривая реализация двумерного массива. Там же индексом что угодно может быть. Хоть "Hello, World!".
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #6  
Старый 28.06.2013, 06:42
Pyro Pyro вне форума
Так проходящий
 
Регистрация: 18.07.2011
Сообщения: 805
Версия Delphi: 7Lite
Репутация: 6063
По умолчанию

Код:
if (data[x + '_' + y] == null) {
  // расчёты и установка data[x + '_' + y]
}
return data[x + '_' + y];
это он запоминает пары входные параметры и результат функции в ассоц массив (tdictionary или сортированный stringlist), и вычисление для каждых входных происходит только раз http://ru.wikipedia.org/wiki/%D0%9C%...%D 0%B8%D1%8F
__________________
>woweook<

Последний раз редактировалось Pyro, 28.06.2013 в 08:42.
Ответить с цитированием
  #7  
Старый 28.06.2013, 22:11
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Только не очень понятно, зачем мучить бедный компьютер строковыми операциями и использованием их результата как индекса, когда можно сделать data[x][y].
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #8  
Старый 28.06.2013, 22:20
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Да все, не актуально больше.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение:
WinMon (30.06.2013)
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 15:20.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter