目前,我正在为计算机科学课程作业中的 Mandelbrot 集等内容开发分形渲染器,并且我想在下面的函数上使用递归而不是迭代,因为它会给我更多分数。
原始迭代函数如下。 (我删除了函数中用于渲染其他分形的某些部分,但我没有包含它们,否则这会太长)
function fractal:compute(x,y)
iteration = 1
local zx = 0
local zy = 0
while iteration < self.maxIterations and zx^2 + zy^2 < 4 do
temp = zx
if self.current == "Mandelbrot" then
zx, zy = Mandelbrot(zx,zy,x,y)
end
iteration = iteration + 1
end
return iteration
end
function Mandelbrot(zx, zy, x, y)
return zx^2-zy^2+x, 2*zx*zy+y
end
我尝试使用几种方法来做到这一点,例如使用:
x^2 + y^2 > 4 or iteration == maxIterations
作为基本情况,但由于某种原因它似乎不起作用 - 例如:
function fractal:compute_Recursively(x,y, cx, cy, count)
if count >= fractal.maxIterations or x^2 + y^2 >= 4 then
return count
else return self.compute_Recursively(x^2-y^2+cx, 2*x*y + cy, cx, cy, count+1)
end
end
function formulae.Mandelbrot_Recursive(x, y, cx, cy, i)
if i >= fractal.maxIterations or x^2 + y^2 >= 4 then
return i
else return formulae.Mandelbrot_R(x^2-y^2+cx, 2*x*y + cy, cx, cy, i+1)
end
end
以我的拙见,在这种情况下递归没有用处。由于您需要计算迭代次数,因此需要采取特殊措施(例如附加参数)来存储当前迭代计数。
但是,下面是代码,您可以通过注释掉其中之一来选择函数的递归或非递归变体。为了使其更美观,并希望获得更多积分,代码变得更加通用。它依赖于一个小型复数库。不使用带有方法的表格。
-- get complex.lua from https://codereview.stackexchange.com/questions/252982/complex-number-class-in-lua.
local complex = require 'complex'
--[[
Get the iteration, at which the recursive function exceeds the limit. Not recursive.
@param function func -- the recursive function to check,
@param number limit -- limit to exceed,
@param number max_iterations -- maximum number of iterations,
@return number -- iteration at which the limit is exceeded, but not more than max_iterations.
--]]
local function iteration (func, limit, max_iterations)
local z, iteration = complex (0), 0
while iteration < max_iterations and z:abs () <= limit do
z, iteration = func (z), iteration + 1
end
return iteration
end
--[[
Get the iteration, at which the recursive function exceeds the limit. Recursive.
@param function func -- the recursive function to check,
@param number limit -- limit to exceed,
@param number max_iterations -- maximum number of iterations,
@param complex z -- current value in the series; 0 by default,
@param number iteration -- the current iteration; 0 by default.
@return number -- iteration at which the limit is exceeded, but not more than max_iterations.
--]]
local function iterationRecursive (func, limit, max_iterations, z, iteration)
local z, iteration = z or complex (0), iteration or 0
if iteration >= max_iterations or z:abs() > limit then
return iteration
end
z, iteration = func (z), iteration + 1
return iterationRecursive (func, limit, max_iterations, z, iteration)
end
--[[
Generate f_c (z) = z^2 + c function for the given c.
@param complex c
@return function
--]]
local function makeMandelbrot (c)
return function (z)
return z ^ 2 + c
end
end
local limit, max_iterations = 2, 100
local range = {-1, -0.5, 0, 0.5, 1}
for _, re in ipairs (range) do
for _, im in ipairs (range) do
local c = complex (re, im)
local mandelbrot = makeMandelbrot (c)
--local iter = iteration (mandelbrot, limit, max_iterations)
local iter = iterationRecursive (mandelbrot, limit, max_iterations)
print ('c = ' .. tostring (c) .. ':\t' .. tostring (iter) .. ' iterations')
end
end