2024-06-08 08:31:21 发布
网友
我想做一个自定义分形
我所做的是创建一个半径为R的圆,假设我们有三个小圆在里面,它们和大的圆接触,它们的大小都一样,我想找到小圆的半径,它是大圆半径的函数
我可以用一个函数计算出半径的公式:
def formula(R): return ((sqrt(3)*R)/(sqrt(3)+2))
如果有人需要我可以解释
我现在要做的是编写一个递归函数,用pygame再次对每个小圆圈执行此操作
作为一种小吃/练习,我将其实现为一个带有React的交互式玩具(使用@Yevhenii M.的答案公式计算半径)。(向下滚动并点击“Run”查看它的运行情况!)你知道吗
分形的实质(自然)在drawFractal函数中;您应该能够将它改编成Python/PyGame,用drawCircle代替框架中画圆的东西。你知道吗
drawFractal
drawCircle
const nextRadius = (r1, n) => (r1 * Math.sin(Math.PI / n)) / (1 + Math.sin(Math.PI / n)); function drawFractal( circleStyle, levels, branches, startRadius, anglePerLevel ) { const circles = []; function drawCircle(cx, cy, r, transform = null) { circles.push( <circle cx={cx} cy={cy} r={r} style={circleStyle} key={circles.length} /> ); } function drawLevel(centerX, centerY, lastRadius, n, levelsLeft) { const radius = nextRadius(lastRadius, n); const distance = lastRadius - radius; const level = levels - levelsLeft; for (var i = 0; i < n; i++) { const angle = (i / n + level * anglePerLevel) * Math.PI * 2; const x = Math.sin(angle) * distance; const y = Math.cos(angle) * distance; drawCircle(centerX + x, centerY + y, radius); if (levelsLeft > 0) { drawLevel(centerX + x, centerY + y, radius, n, levelsLeft - 1); } } } drawCircle(0, 0, startRadius); drawLevel(0, 0, startRadius, branches, levels); return circles; } function App() { const [branches, setBranches] = React.useState(3); const [levels, setLevels] = React.useState(3); const [twist, setTwist] = React.useState(0); const contents = drawFractal( { fill: "none", stroke: "red", strokeWidth: 1 }, levels, branches, 250, twist ); return ( <div className="App"> <label> Branches <input type="range" min={1} max={15} value={branches} onInput={e => setBranches(e.target.valueAsNumber)} /> </label> <label> Levels <input type="range" min={1} max={7} value={levels} onInput={e => setLevels(e.target.valueAsNumber)} /> </label> <label> Twist <input type="range" min={-1} max={1} step={0.001} value={twist} onInput={e => setTwist(e.target.valueAsNumber)} /> </label> <hr /> <svg viewbox="0 0 1000 1000" width={500} height={500} style={{ border: "1px solid black" }} > <g transform="translate(250 250)">{contents}</g> </svg> </div> ); } const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement);
定义从原点(0,0)到Equilateral triangle的角点的规范化向量:
sin60 = math.sin(math.pi/3) # math.sqrt(3) / 2 tri_pt = [[-sin60, 0.5], [sin60, 0.5], [0, -1]]
使用"Radius of inner circles given radius of outer circle and number of inner circles in circular fractal"中给出的公式计算内圆的半径和从中心到内圆中心点的距离:
in_r = radius * math.sin(math.pi/3) / (math.sin(math.pi/3)+1) in_cpt_d = radius - in_r
计算回路中内圆的中心点:
colors = [(255, 0, 0), (0, 0, 255), (255, 255, 0)] for pt, color in zip(tri_pt, colors): in_cpt = (cpt[0] + pt[0] * in_cpt_d), (cpt[1] + pt[1] * in_cpt_d) pygame.draw.circle(window, color, (round(in_cpt[0]), round(in_cpt[1])), round(in_r), 1)
请参见使用递归函数的示例:
import pygame, math def innerCircles(cpt, radius, depth): if depth == 4: return sin60 = math.sin(math.pi/3) # math.sqrt(3) / 2 tri_pt = [[-sin60, 0.5], [sin60, 0.5], [0, -1]] in_r = radius * sin60 / (sin60+1) in_cpt_d = radius - in_r colors = [(255, 0, 0), (0, 0, 255), (255, 255, 0)] for pt, color in zip(tri_pt, colors): in_cpt = (cpt[0] + pt[0] * in_cpt_d), (cpt[1] + pt[1] * in_cpt_d) pygame.draw.circle(wnd, color, (round(in_cpt[0]), round(in_cpt[1])), round(in_r), 1) innerCircles(in_cpt, in_r, depth+1) pygame.init() wnd = pygame.display.set_mode((500, 500)) clock = pygame.time.Clock() run = True while run: clock.tick(60) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False wnd.fill(0) cpt = (250, 250) radius = 200 pygame.draw.circle(wnd, (255, 255, 255), cpt, radius+1, 3) innerCircles(cpt, radius, 0) pygame.display.flip()
作为一种小吃/练习,我将其实现为一个带有React的交互式玩具(使用@Yevhenii M.的答案公式计算半径)。(向下滚动并点击“Run”查看它的运行情况!)你知道吗
分形的实质(自然)在
drawFractal
函数中;您应该能够将它改编成Python/PyGame,用drawCircle
代替框架中画圆的东西。你知道吗const nextRadius = (r1, n) => (r1 * Math.sin(Math.PI / n)) / (1 + Math.sin(Math.PI / n)); function drawFractal( circleStyle, levels, branches, startRadius, anglePerLevel ) { const circles = []; function drawCircle(cx, cy, r, transform = null) { circles.push( <circle cx={cx} cy={cy} r={r} style={circleStyle} key={circles.length} /> ); } function drawLevel(centerX, centerY, lastRadius, n, levelsLeft) { const radius = nextRadius(lastRadius, n); const distance = lastRadius - radius; const level = levels - levelsLeft; for (var i = 0; i < n; i++) { const angle = (i / n + level * anglePerLevel) * Math.PI * 2; const x = Math.sin(angle) * distance; const y = Math.cos(angle) * distance; drawCircle(centerX + x, centerY + y, radius); if (levelsLeft > 0) { drawLevel(centerX + x, centerY + y, radius, n, levelsLeft - 1); } } } drawCircle(0, 0, startRadius); drawLevel(0, 0, startRadius, branches, levels); return circles; } function App() { const [branches, setBranches] = React.useState(3); const [levels, setLevels] = React.useState(3); const [twist, setTwist] = React.useState(0); const contents = drawFractal( { fill: "none", stroke: "red", strokeWidth: 1 }, levels, branches, 250, twist ); return ( <div className="App"> <label> Branches <input type="range" min={1} max={15} value={branches} onInput={e => setBranches(e.target.valueAsNumber)} /> </label> <label> Levels <input type="range" min={1} max={7} value={levels} onInput={e => setLevels(e.target.valueAsNumber)} /> </label> <label> Twist <input type="range" min={-1} max={1} step={0.001} value={twist} onInput={e => setTwist(e.target.valueAsNumber)} /> </label> <hr /> <svg viewbox="0 0 1000 1000" width={500} height={500} style={{ border: "1px solid black" }} > <g transform="translate(250 250)">{contents}</g> </svg> </div> ); } const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement);
; ^{pr2}$ ;定义从原点(0,0)到Equilateral triangle的角点的规范化向量:
使用"Radius of inner circles given radius of outer circle and number of inner circles in circular fractal"中给出的公式计算内圆的半径和从中心到内圆中心点的距离:
计算回路中内圆的中心点:
请参见使用递归函数的示例:
相关问题 更多 >
编程相关推荐