Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 537b577

Browse files
Add files via upload
1 parent 26ea2a5 commit 537b577

File tree

1 file changed

+217
-0
lines changed

1 file changed

+217
-0
lines changed

‎pythagorean tree.jl‎

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
# coding: utf-8
2+
3+
# In[1]:
4+
5+
6+
#fractal is one of the interesting topics in geometry
7+
#it is usually described by a recursive function
8+
#voila,here we are!
9+
using Plots
10+
11+
12+
# In[2]:
13+
14+
15+
#create rectangle shape
16+
rectangle(top_left,top_right,bottom_left,
17+
bottom_right)=Shape([(top_left[1],top_left[2]),
18+
(top_right[1],top_right[2]),
19+
(bottom_right[1],bottom_right[2]),
20+
(bottom_left[1],bottom_left[2])])
21+
22+
23+
# In[3]:
24+
25+
26+
#compute euclidean distance
27+
function euclidean_distance(point1,point2)
28+
return ((point1[1]-point2[1])^2+(point1[2]-point2[2])^2)
29+
end
30+
31+
32+
# In[4]:
33+
34+
35+
#simple solution to get coefficients of the equation
36+
function get_line_params(x1,y1,x2,y2)
37+
38+
slope=(y1-y2)/(x1-x2)
39+
intercept=y1-slope*x1
40+
41+
return slope,intercept
42+
43+
end
44+
45+
46+
# In[5]:
47+
48+
49+
#standard solution to quadratic equation
50+
function solve_quadratic_equation(A,B,C)
51+
x1=(-B+√(B^2-4*A*C))/(2*A)
52+
x2=(-B-√(B^2-4*A*C))/(2*A)
53+
return [x1,x2]
54+
end
55+
56+
57+
# In[6]:
58+
59+
60+
#analytic geometry to compute target datapoints
61+
function get_datapoint(pivot,measure,length,direction="inner")
62+
63+
#for undefined slope
64+
if pivot[1]==measure[1]
65+
y1=pivot[2]+length
66+
y2=pivot[2]-length
67+
x1=pivot[1]
68+
x2=pivot[1]
69+
70+
#for general cases
71+
else
72+
73+
#get line equation
74+
slope,intercept=get_line_params(pivot[1],pivot[2],
75+
measure[1],measure[2],)
76+
77+
#solve quadratic equation
78+
A=1
79+
B=-2*pivot[1]
80+
C=pivot[1]^2-length^2/(slope^2+1)
81+
x1,x2=solve_quadratic_equation(A,B,C)
82+
83+
#get y from line equation
84+
y1=slope*x1+intercept
85+
y2=slope*x2+intercept
86+
87+
end
88+
89+
if direction=="inner"
90+
91+
#take the one between pivot and measure points
92+
if euclidean_distance((x1,y1),measure)<euclidean_distance((x2,y2),measure)
93+
datapoint=(x1,y1)
94+
else
95+
datapoint=(x2,y2)
96+
end
97+
98+
else
99+
100+
#take the one farther away from measure points
101+
if euclidean_distance((x1,y1),measure)>euclidean_distance((x2,y2),measure)
102+
datapoint=(x1,y1)
103+
else
104+
datapoint=(x2,y2)
105+
end
106+
107+
end
108+
109+
return datapoint
110+
111+
end
112+
113+
114+
# In[7]:
115+
116+
117+
#recursively plot symmetric pythagorean tree at 45 degree
118+
# https//larryriddle.agnesscott.org/ifs/pythagorean/pythTree.htm
119+
function pythagorean_tree(top_left,top_right,bottom_left,
120+
bottom_right,current_angle,line_len,n)
121+
122+
#plot square
123+
plot!(rectangle(top_left,top_right,bottom_left,bottom_right))
124+
125+
if n==0
126+
return
127+
else
128+
129+
#find mid point
130+
#midpoint has to satisfy two conditions
131+
#it has to be on the same line as bottom_left and bottom_right
132+
#assume this line follows y=kx+b
133+
#the midpoint is (x,kx+b)
134+
#bottom_left is (α,kα+b),bottom_right is (δ,kδ+b)
135+
#the euclidean distance between midpoint and bottom_left should be
136+
#half of the euclidean distance between bottom_left and bottom_right
137+
#(x-α)**2+(kx+b-kα-b)**2=((α-δ)**2+(kα+b-kδ-b)**2)/4
138+
#apart from x,everything else in the equation is constant
139+
#this forms a simple quadratic solution to get two roots
140+
#one root would be between bottom_left and bottom_right which yields midpoint
141+
#and the other would be farther away from bottom_right
142+
#this function solves the equation via (-B+(B**2-4*A*C)**0.5)/(2*A)
143+
#alternatively,you can use scipy.optimize.root
144+
#the caveat is it does not offer both roots
145+
#a wrong initial guess could take you to the wrong root
146+
bottom_mid=get_datapoint(bottom_left,bottom_right,line_len/2)
147+
top_mid=get_datapoint(top_left,top_right,line_len/2)
148+
149+
#compute the top point of a triangle
150+
#the computation is similar to midpoint
151+
#the euclidean distance between triangle_top and top_mid should be
152+
#half of the distance between top_mid and bottom_mid
153+
triangle_top=get_datapoint(top_mid,bottom_mid,
154+
line_len/2,"outer")
155+
156+
#get top left for right square
157+
#the computation is similar to midpoint
158+
#the euclidean distance between triangle_top and rightsq_topleft
159+
#should be the same as the distance between triangle_top and top_left
160+
rightsq_topleft=get_datapoint(triangle_top,top_left,
161+
line_len/((2)),"outer")
162+
163+
#get midpoint of the diagonal between rightsq_topleft and top_right
164+
#the computation is similar to midpoint
165+
#the euclidean distance between rightsq_diag_mid and rightsq_topleft
166+
#should be half of the distance between rightsq_topleft and top_right
167+
rightsq_diag_mid=get_datapoint(top_right,rightsq_topleft,line_len/2)
168+
rightsq_topright=get_datapoint(rightsq_diag_mid,triangle_top,
169+
line_len/2,"outer")
170+
171+
#get top left and right for left square similar to right square
172+
leftsq_topleft=get_datapoint(triangle_top,rightsq_topright,
173+
line_len,"outer")
174+
leftsq_topright=get_datapoint(triangle_top,top_right,
175+
line_len/((2)),"outer")
176+
177+
#recursive do the same for left square
178+
pythagorean_tree(leftsq_topleft,leftsq_topright,
179+
top_left,triangle_top,current_angle+45,
180+
line_len/((2)),n-1)
181+
182+
#recursive do the same for right square
183+
pythagorean_tree(rightsq_topleft,rightsq_topright,
184+
triangle_top,top_right,current_angle-45,
185+
line_len/((2)),n-1)
186+
187+
end
188+
189+
end
190+
191+
192+
# In[8]:
193+
194+
195+
#initialize
196+
top_left=(0,0)
197+
top_right=(1,0)
198+
bottom_left=(0,-1)
199+
bottom_right=(1,-1)
200+
n=4
201+
current_angle=0
202+
line_len=euclidean_distance(top_left,top_right);
203+
204+
205+
# In[9]:
206+
207+
208+
#viz
209+
gr(size=(250,200))
210+
fig=plot(legend=false,grid=false,axis=false,ticks=false,
211+
)
212+
213+
pythagorean_tree(top_left,top_right,bottom_left,
214+
bottom_right,current_angle,line_len,n)
215+
fig
216+
217+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /