分形科赫曲线

2 投票
3 回答
7749 浏览
提问于 2025-04-17 02:15

我的项目是关于天线设计的,使用Python生成一个.nec文件,这样我就可以在软件中建模分形天线,并优化它们以获得最佳性能。这个程序可以处理多种分形天线,包括以下几种:

  • Koch曲线
  • Hilbert曲线
  • Koch雪花

别担心,这不是作业。我正在做一个关于分形天线的演讲,想要自动化设计过程,不然手动做起来太麻烦了。

不幸的是,我在计算Koch曲线的中心点时遇到了问题。下面是软件中Koch曲线的图像;请注意,我还有一些几何错误需要解决。

Koch Fractal in 4NEC2

这里是使用迭代级别3和段大小0.305米生成的Python脚本的坐标。

目前让我感到困扰的Python脚本如下:

.NEC文件

坐标

4NEC2_Generator.py代码

完整项目

从Koch曲线的图像中可以看出,它的中心偏离了一点。我用来计算完整长度的公式是:

Center Point Equation

其中:

 l = total side-length (referenced from the bottom) of the Koch Curve
 s = segment size (my segment size was 0.305m, they should all be equal)
 n = number of iterations

有没有人知道我为什么找不到中心点?

谢谢,

Austin

3 个回答

1

我决定使用我之前的传统代码,这主要是因为一个初步的因素:我的kochCurve()代码是基于Koch曲线下面的总长度,而之前我一直认为它是决定每个小段的长度。因此,中心点就很容易确定了。

下面是我的代码生成的一些图片:

主面板

二维辐射切片

三维辐射图案

谢谢大家的帮助!

2

你的问题出在计算边长的新长度时使用了递归。

def kochCurve(level, lengthSide):

    if(level == 0):
        ut.fd(lengthSide)
    else:
        newLengthSide = level/3.0     ## <-- Wrong.
        newLevel = level - 1

        kochCurve(newLevel, newLengthSide)
        ut.lt(60)
        kochCurve(newLevel, newLengthSide)
        ut.rt(120)
        kochCurve(newLevel, newLengthSide)
        ut.lt(60)
        kochCurve(newLevel, newLengthSide)

你在计算newLengthSide时,没有参考当前的边长。正确的写法应该是:

        newLengthSide = lengthSide / 3.0

你的段落长度是0.33333的原因是因为你忽略了传入的0.305,而是从1/3.0开始计算。

我不太确定传入的值应该代表什么,所以这可能不是正确的写法,但这就是为什么你的段落长度不对的原因。

3

也许你可以尝试用更标准的方式重新实现你的迭代计算。

关于在Python中实现好的Koch曲线算法的答案可以在这里找到:

如何实现Koch曲线?

(还有问题中的原始代码也可能对你有很大帮助)

编辑:

我创建了一个脚本,使用了提供链接中的代码,以及Cairo和Python图像库(PIL)来渲染图像。希望这对你有帮助:

#!/bin/env python
# coding: utf-8

import math

angles = [math.radians(60*x) for x in range(6)]
sines = [math.sin(x) for x in angles]
cosin = [math.cos(x) for x in angles]

def L(angle, coords, jump):
    return (angle + 1) % 6
def R(angle, coords, jump):
    return (angle + 4) % 6
def F(angle, coords, jump):
    coords.append(
        (coords[-1][0] + jump * cosin[angle],
         coords[-1][1] + jump * sines[angle]))
    return angle

decode = dict(L=L, R=R, F=F)

def koch(steps, length=200, startPos=(0,0)):
    pathcodes="F"
    for i in xrange(steps):
        pathcodes = pathcodes.replace("F", "FLFRFLF")

    jump = float(length) / (3 ** steps)
    coords = [startPos]
    angle = 0

    for move in pathcodes:
        angle = decode[move](angle, coords, jump)

    return coords


TOTALWIDTH = 1000

points = koch(3,TOTALWIDTH,(-TOTALWIDTH/2,0))
print points


# optional part, shows an image with Y axis(good for debugging)
import cairo, Image

width = TOTALWIDTH
height = int(TOTALWIDTH*0.32)
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
cr = cairo.Context(surface)
cr.set_source_rgb(1,1,1)
cr.rectangle(0, 0, width, height)
cr.fill()
cr.translate(width*0.5, height*0.95)
cr.scale(1, -1)

# red Y axis:
cr.set_source_rgb(1,0,0)
cr.move_to(0,0)
cr.line_to(0,300)
cr.stroke()

cr.set_source_rgb(0,0,0)
cr.set_line_width(0.5)
cr.move_to(*points[0])
for n in range(len(points)):
    cr.line_to(*points[n])
cr.stroke()

im = Image.frombuffer("RGBA", (width, height), surface.get_data(), "raw", "BGRA", 0,1)
im.show()

撰写回答