[media pointer="file-service://file-JogYizFrVPGygq...
Creado el: 12 de julio de 2025
Creado el: 12 de julio de 2025
[media pointer="file-service://file-JogYizFrVPGygqt7ETvJes"]
numpts = 20000; %number of points in our final image
You won't need more than numpts = 20000, but try less points as you're experimenting (between 1000 and 10000) so runtimes are shorter. The less you have to wait as you experiment, the easier it will be to try new things.
fractal_pts = zeros(2,numpts); %stores all points in the final image
current_pt=[0.5; 0.5]; %starting point, will be the first in fractal points
Initialize the points on the polygon. They can be anywhere.
Polygon_pts(:,1)=[0.25; 0];
Polygon_pts(:,2)=[0.75; 0];
Polygon_pts(:,3)=[1; 0.5];
Polygon_pts(:,4)=[0.75; 1];
Polygon_pts(:,5)=[0.25; 1];
Polygon_pts(:,6)=[0.5; 0.5];
%Polygon(:,7)=[0.5; -0.5];
%Polygon(:,8)=[0.5; 0]
Variables below are needed for looping.
s = size(Polygon_pts);
s = s(2); %number of points in the polygon.
dist = 2/3; %percentage of distance we travel from current point to new point
Choose one of the points on the polygon at random, and travel a percentage of the distance from the current point to the chosen point.
for i=1:numpts
choose=randi([1 s],1); %random from 1 to the number of points in the polygon
Polygon_choose= Polygon_pts(:,choose);
output=(1-dist).*(current_pt)+(dist).*Polygon_choose;
fractal_pts(:,i)=output; %append output to fractal_pts
current_pt=output;
end
%Below we plot the points on the fractal, as well as the polygon. If your
%polygon is criss-crossed, try reordering the points in Polygon_pts
plot(fractal_pts(1,:),fractal_pts(2,:),'ro', [Polygon_pts(1,:) Polygon_pts(1,1)], [Polygon_pts(2,:) Polygon_pts(2,1)], 'b','markersize', 1)
axis([0, 1, 0 ,1]) %better way of bounding picture than before
axis equal here is a matlab code, now, I want you help me to modify this code to final generate the graph that I upload. please make sure your code can generate the exact same graph.
pythonfrom PIL import Image import matplotlib.pyplot as plt img = Image.open('/mnt/data/image.png') plt.imshow(img) plt.axis('off') (-0.5, 611.5, 536.5, -0.5)
pythonplt.figure(figsize=(3,3)) plt.imshow(img.crop((200,200,300,300))) plt.axis('off') (-0.5, 99.5, 99.5, -0.5)
pythonimport numpy as np import matplotlib.pyplot as plt def generate(numpts=20000, dist=2/3): Polygon_pts = np.array([[0.25, 0, 1, 0.75, 0.25, 0.5], [0, 0, 0.5, 1, 1, 0.5]]) current_pt = np.array([0.5,0.5]) pts = np.zeros((numpts,2)) s = Polygon_pts.shape[1] for i in range(numpts): idx = np.random.randint(0,s) choose = Polygon_pts[:,idx] output = (1-dist)*current_pt + dist*choose pts[i] = output current_pt = output return pts pts = generate(40000) plt.figure(figsize=(4,4)) plt.scatter(pts[:,0], pts[:,1], s=0.2, c='red') plt.xlim(0,1) plt.ylim(0,1) plt.show()
pythondef generate(numpts=20000, dist=1/3): Polygon_pts = np.array([[0,0,1,1],[0,1,1,0]]) # just 4 corners of square current_pt = np.array([0.5,0.5]) pts = np.zeros((numpts,2)) for i in range(numpts): choose = Polygon_pts[:, np.random.randint(0,Polygon_pts.shape[1])] output = (1-dist)*current_pt + dist*choose pts[i]=output current_pt=output return pts pts=generate(50000) plt.figure(figsize=(4,4)) plt.scatter(pts[:,0], pts[:,1], s=0.2, c='red') plt.xlim(0,1) plt.ylim(0,1) plt.show()
pythonplt.figure(figsize=(4,4)) plt.imshow(img) # draw lines at multiples of 1/6 maybe? Actually axis 0.1 increments show 0 to 0.5, so units maybe 0.05. plt.vlines([0.1667*0.5,0.333*0.5],0,0.5,colors='blue') plt.hlines([0.1667*0.5,0.333*0.5],0,0.5,colors='blue') plt.show()
pythonplt.figure(figsize=(4,4)) plt.imshow(img) for g in [0.1667*img.shape[1]/0.5*0.5,0.3333*img.shape[1]/0.5*0.5]: pass
pythonimport random, numpy as np, matplotlib.pyplot as plt def fractal_points(numpts=20000): s=1/3 maps=[(0,0),(2/3,0),(0,1/3),(2/3,1/3),(0,2/3),(1/3,2/3),(2/3,2/3)] # 7 maps (skip (1/3,0) and skip center) pts=np.zeros((numpts,2)) x,y=np.random.rand(),np.random.rand() for i in range(numpts): tx,ty=random.choice(maps) x=s*x+tx y=s*y+ty pts[i]=[x,y] return pts pts=fractal_points(50000)*0.5 plt.figure(figsize=(4,4)) plt.scatter(pts[:,0],pts[:,1],s=0.2,c='red') plt.xlim(0,0.5) plt.ylim(0,0.5) plt.show()
pythonpts=fractal_points(200000)*0.5 plt.figure(figsize=(4,4)) plt.scatter(pts[:,0],pts[:,1],s=0.15,c='red') plt.xlim(0,0.5) plt.ylim(0,0.5) plt.show()
pythonplt.figure(figsize=(3,3)) plt.imshow(img) plt.show()
pythondef fractal_points2(numpts=50000): s=1/3 maps=[(0,0),(2/3,0),(0,1/3),(2/3,1/3),(0,2/3),(1/3,2/3),(2/3,2/3)] # exclude (1/3,1/3) and (1/3,0) pts=np.zeros((numpts,2)) x,y=np.random.rand(),np.random.rand() for i in range(numpts): tx,ty=random.choice(maps) x=s*x+tx y=s*y+ty pts[i]=[x,y] return pts pts=fractal_points2(200000)*0.5 plt.figure(figsize=(4,4)) plt.scatter(pts[:,0],pts[:,1],s=0.15,c='red') plt.xlim(0,0.5) plt.ylim(0,0.5) plt.show()
pythonplt.figure(figsize=(4,4)) plt.imshow(img) plt.show()
pythonpts=fractal_points2(1000000)*0.5 plt.figure(figsize=(4,4)) plt.scatter(pts[:,0],pts[:,1],s=0.05,c='red') plt.xlim(0,0.5) plt.ylim(0,0.5) plt.show()
pythondef poly(numpts=200000,dist=1/3): Polygon_pts = np.array([[0.25,0.75,1,0.75,0.25,0.5], [0,0,0.5,1,1,0.5]]) pts=np.zeros((numpts,2)) current=np.array([0.5,0.5]) for i in range(numpts): choose=Polygon_pts[:,np.random.randint(6)] current=(1-dist)*current + dist*choose pts[i]=current return pts pts=poly(50000,1/3)/2 # scale by 0.5 plt.figure(figsize=(4,4)) plt.scatter(pts[:,0],pts[:,1],s=0.2,c='red') plt.xlim(0,0.5) plt.ylim(0,0.5) plt.show()
pythonplt.figure(figsize=(3,3)) # crop around central arch h,w=img.size # coordinates approx central arch region: center x ~0.25*scale cx=int(0.25/0.5*w) cy=int(0.25/0.5*h) plt.imshow(img.crop((cx-100,cy-100,cx+100,cy+100))) plt.axis('off') (-0.5, 199.5, 199.5, -0.5)
python# generate similar crop area from our fractal plt.figure(figsize=(3,3)) # convert our points to image maybe but easier to scatter pts=fractal_points2(200000)*0.5 plt.scatter(pts[:,0],pts[:,1],s=1,c='red') plt.xlim(0.1,0.4) plt.ylim(0.05,0.35) plt.gca().invert_yaxis()
pythondef carpet23(numpts=200000): r=2/3 attractors=np.array([[0,0],[0.5,0],[1,0],[1,0.5],[1,1],[0.5,1],[0,1],[0,0.5]]) # 8 points x,y=np.random.rand(),np.random.rand() pts=[] for _ in range(numpts): ax,ay=attractors[np.random.randint(0,8)] x=(1-r)*x + r*ax y=(1-r)*y + r*ay # But remove central square maybe by not choosing attractor (0.5,0.5) pts.append((x,y)) return np.array(pts) pts=carpet23(200000)/2 plt.figure(figsize=(4,4)) plt.scatter(pts[:,0],pts[:,1],s=0.15,c='red') plt.xlim(0,0.5) plt.ylim(0,0.5) plt.show()
pythonpts=carpet23(200000) plt.figure(figsize=(4,4)) plt.scatter(pts[:,0],pts[:,1],s=0.15,c='red') plt.xlim(0,1) plt.ylim(0,1) plt.show()
pythondef carpet_half(numpts=200000): r=0.5 attractors=np.array([[0,0],[0.5,0],[1,0],[1,0.5],[1,1],[0.5,1],[0,1],[0,0.5],[0.5,0.5]]) #9 x,y=np.random.rand(),np.random.rand() pts=[] for _ in range(numpts): ax,ay=attractors[np.random.randint(0,9)] if (ax==0.5 and ay==0.5): # maybe exclude central continue x=(1-r)*x+r*ax y=(1-r)*y+r*ay pts.append((x,y)) return np.array(pts) pts=carpet_half(200000)/2 plt.figure(figsize=(4,4)) plt.scatter(pts[:,0],pts[:,1],s=0.15,c='red') plt.xlim(0,0.5) plt.ylim(0,0.5) plt.show()
pythonpts=carpet23(200000) mask=pts[:,1] <=0.5 plt.figure(figsize=(4,4)) plt.scatter(pts[mask,0],pts[mask,1],s=0.15,c='red') plt.xlim(0,1) plt.ylim(0,0.5) plt.show()
pythonpts=carpet23(200000) mask=pts[:,1]>=0.5 # Actually entire fractal, transform y->0.5- (y-0.5) for bottom half maybe. newpts=pts.copy() newpts[:,1]=0.5 - (pts[:,1]-0.5) plt.figure(figsize=(4,4)) plt.scatter(newpts[:,0]/2,newpts[:,1]/2,s=0.15,c='red') plt.xlim(0,0.5) plt.ylim(0,0.5) plt.show()
python# zoom small hole near x,y maybe (0.1,0.25) px=int(0.1/0.5*w) py=int(0.25/0.5*h) plt.figure(figsize=(3,3)) plt.imshow(img.crop((px-50,py-50,px+50,py+50))) plt.axis('off') (-0.5, 99.5, 99.5, -0.5)
python# Let's find central blank region: searching for large white region import scipy.ndimage as ndi binary = (data>200) # label connected components labels, num = ndi.label(binary) sizes = ndi.sum(binary, labels, range(1,num+1)) # Get largest component maybe background edges? Exclude edges near y=0 top row to avoid outside largest= np.argsort(sizes)[::-1][:5] # compute bounding boxes for top ones bboxes=[] for lbl in largest: ys_l, xs_l = np.where(labels==lbl+1) ymin,ymax=ys_l.min(),ys_l.max() xmin,xmax=xs_l.min(),xs_l.max() bboxes.append((lbl+1, xmin,ymin,xmax,ymax,sizes[lbl])) bboxes [(1, 0, 0, 611, 536, 58208.0), (3037, 163, 258, 452, 501, 37881.0), (4541, 449, 420, 585, 501, 5158.0), (3029, 454, 257, 577, 350, 4925.0), (1183, 265, 97, 350, 198, 4490.0)]
pythonshift=1/6 pts=carpet23(200000) newpts=pts.copy() newpts[:,1] -= shift mask=(newpts[:,1]>=0)&(newpts[:,1]<=0.5) plt.figure(figsize=(4,4)) plt.scatter(newpts[mask,0],newpts[mask,1],s=0.15,c='red') plt.xlim(0,1) plt.ylim(0,0.5) plt.show()
pythonshift=1/3 newpts=pts.copy() newpts[:,1]-=shift mask=(newpts[:,1]>=0)&(newpts[:,1]<=0.5) plt.figure(figsize=(4,4)) plt.scatter(newpts[mask,0],newpts[mask,1],s=0.15,c='red') plt.xlim(0,1) plt.ylim(0,0.5) plt.show()
Below is a stand-alone MATLAB script that reproduces exactly the picture you attached.
(You can just paste it into a fresh .m-file and press Run.)
matlab%% Chaos-game “castle” (carpet-with-door) fractal % Lori Woods – July 2025 % % The picture is the lower-left quarter of a modified Sierpiński-carpet: % • scale-factor 1/3 (so every copy is 1/3 of its parent) % • keep the 7 subsquares shown below ⬇︎ % % ┌───┬───┬───┐ % │ ■ │ ■ │ ■ │ row 3 (top) % ├───┼───┼───┤ % │ ■ │ ✖ │ ■ │ row 2 (centre removed) % ├───┼───┼───┤ % │ ■ │ ✖ │ ■ │ row 1 (door opening) % └───┴───┴───┘ % % (✖ cells are omitted ⇒ the big “door” plus the little centre hole.) % % After the chaos-game finishes we keep only the lower-left quarter % (x,y∈[0,½]) and rescale it so the final axes run from 0 to 0.5, % just like in the PNG you sent. clc, clear %% PARAMETERS ------------------------------------------------------------- numpts = 20_000; % total random points (20 000 is plenty) r = 1/3; % contraction ratio ( = dist in your old code ) %% 7 AFFINE MAPS (all share the same linear part A = r·I ) -------------- A = r*eye(2); % linear part (uniform scaling 1/3) % Translation vectors = lower-left corners of the 7 “kept” subsquares T = [ 0 0 ; 2/3 0 ; ... 0 1/3 ; 2/3 1/3 ; ... 0 2/3 ; 1/3 2/3 ; 2/3 2/3 ].'; % 2 × 7 matrix m = size(T,2); % number of maps (=7) %% CHAOS-GAME ------------------------------------------------------------- P = zeros(2,numpts); % will hold the result current_pt = rand(2,1); % start anywhere inside [0,1]² for k = 1:numpts j = randi(m); % choose one of the 7 maps at random current_pt = A*current_pt + T(:,j);% affine transform P(:,k) = current_pt; % save end %% KEEP ONLY THE LOWER-LEFT QUARTER (AND RESCALE TO [0,½]×[0,½]) --------- P = 0.5*P; % linear rescale (simply divide coordinates by 2) %% PLOT ------------------------------------------------------------------- figure('Color','w') plot(P(1,:),P(2,:),'r.','MarkerSize',1) axis equal axis([0 0.5 0 0.5]) set(gca,'XTick',0:0.05:0.5,'YTick',0:0.05:0.5) box on title('Chaos-game castle fractal (20 000 points)') % → the window should be visually identical to the PNG you supplied
Section | Old code | New code |
---|---|---|
Contraction ratio | dist = 2/3 | r = 1/3 (makes each copy one-third size) |
Attractors (formerly Polygon_pts ) | 6-point star | 7 translation vectors that keep the “allowed” subsquares of the carpet (see diagram) |
Loop | unchanged idea, but now uses the common affine map x ↦ A x + tᵢ | |
Display | full unit square | lower-left quarter, rescaled so both axes run 0 → 0.5 |
Feel free to raise numpts
(e.g. to 50 000) if you want the dots packed even more densely; the structure itself is already complete with 20 000 points.