You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
3.4 KiB
124 lines
3.4 KiB
3 years ago
|
%--------------------------
|
||
|
% @Author: Jingqiao Hu
|
||
|
% @Date: 2021-12-16 17:19:07
|
||
|
% @LastEditTime: 2021-12-17 15:15:04
|
||
|
|
||
|
% assume length of microx = microx, i.e. dx = 1
|
||
|
%--------------------------
|
||
|
function [bnodes] = generateCVT(nelx, nely, microx, rho)
|
||
|
|
||
|
% e1 = 1; nu1 = 0.3;
|
||
|
|
||
|
globalx = nelx * microx;
|
||
|
globaly = nely * microx;
|
||
|
|
||
|
% [~, fixeddofs, F, ~] = designDomain(optDesign, globalx, globaly, vF);
|
||
|
|
||
|
% rho = top88(globalx, globaly, v0, e1, nu1, F, fixeddofs);
|
||
|
% save rho rho;
|
||
|
% load("data/mat/rho.mat");
|
||
|
|
||
|
% generate quadtree for seeds of CVT
|
||
|
min_size = microx / 4;
|
||
|
max_size = microx / 2;
|
||
|
[blocks, bnodes] = quadtree1(rho, min_size, max_size);
|
||
|
hold on; scatter(bnodes(:,1), bnodes(:,2),8,'filled','k');
|
||
|
|
||
|
% transform to [-nelx/2, -nely,2] & [nelx/2, nely/2];
|
||
|
bnodes(:,1) = bnodes(:,1) - globalx / 2;
|
||
|
bnodes(:,2) = bnodes(:,2) - globaly / 2;
|
||
|
write_seeds(bnodes);
|
||
|
|
||
|
figure; voronoi(bnodes(:,1), bnodes(:,2)); axis equal;
|
||
|
% bnodes(100,1) = bnodes(100,1) + 0.8;
|
||
|
% figure(3); voronoi(bnodes(:,1), bnodes(:,2));
|
||
|
end
|
||
|
|
||
|
function write_seeds(bnodes)
|
||
|
fileID = fopen('data/seeds.cin','w');
|
||
|
fprintf(fileID,'%f %f\n',bnodes');
|
||
|
fclose(fileID);
|
||
|
end
|
||
|
|
||
|
function [blocks, bidx] = quadtree1(rho, min_size, max_size)
|
||
|
|
||
|
% S = qtdecomp(rho, 0.5, [min_size, max_size]); % split-version
|
||
|
S = qtdecomp(rho, @density_filter, 0.45, [min_size, max_size]); % density-version
|
||
|
blocks = zeros(size(S));
|
||
|
|
||
|
show_division(S);
|
||
|
|
||
|
dim = max_size;
|
||
|
while dim >= min_size
|
||
|
numblocks = length(find(S == dim));
|
||
|
|
||
|
if (numblocks > 0)
|
||
|
vals = qtgetblk(rho, S, dim);
|
||
|
|
||
|
valmodes = zeros(size(vals));
|
||
|
for blknum = 1:size(vals,3)
|
||
|
valmodes(:,:,blknum) = mode(vals(:,:,blknum),'all');
|
||
|
end
|
||
|
|
||
|
blocks = qtsetblk(blocks, S, dim, valmodes);
|
||
|
end
|
||
|
dim = dim / 2;
|
||
|
end
|
||
|
% figure(2); imshow(1-blocks); axis equal
|
||
|
|
||
|
bidx = blocks_idx(rho, S, min_size, max_size);
|
||
|
end
|
||
|
|
||
|
function dosplit = density_filter(A, threshold, dims)
|
||
|
|
||
|
meanVals = mean(mean(A,1),2);
|
||
|
dosplit = meanVals > threshold;
|
||
|
|
||
|
dosplit = (dosplit & (size(A,1) > dims(1))) | (size(A,2) > dims(2));
|
||
|
end
|
||
|
|
||
|
function bidx = blocks_idx(rho, S, min_size, max_size)
|
||
|
|
||
|
bidx = [];
|
||
|
|
||
|
dim = min_size;
|
||
|
while dim <= max_size
|
||
|
numblocks = length(find(S == dim));
|
||
|
|
||
|
if (numblocks > 0)
|
||
|
[~, r, c] = qtgetblk(rho, S, dim);
|
||
|
r = r + dim/2; % y
|
||
|
c = c + dim/2; % x
|
||
|
|
||
|
if isempty(bidx)
|
||
|
bidx = [bidx; c, r]; % [x, y]
|
||
|
% hold on; scatter(c, r, 'filled');
|
||
|
else
|
||
|
rc = setdiff([c,r], bidx, "rows");
|
||
|
bidx = [bidx; rc];
|
||
|
% hold on; scatter(rc(:,2), rc(:,1), 'filled');
|
||
|
end
|
||
|
end
|
||
|
dim = dim * 2;
|
||
|
end
|
||
|
bidx(:,2) = size(rho,1) - bidx(:,2);
|
||
|
end
|
||
|
|
||
|
function show_division(S)
|
||
|
blocks = repmat(uint8(0), size(S));
|
||
|
|
||
|
for dim = [512 256 128 64 32 16 8 4 2 1]
|
||
|
numblocks = length(find(S == dim));
|
||
|
|
||
|
if (numblocks > 0)
|
||
|
values = repmat(uint8(1), [dim dim numblocks]);
|
||
|
values(2:dim, 2:dim, :) = 0;
|
||
|
blocks = qtsetblk(blocks, S, dim, values);
|
||
|
end
|
||
|
end
|
||
|
|
||
|
blocks(end, 1:end) = 1;
|
||
|
blocks(1:end, end) = 1;
|
||
|
|
||
|
figure(1); clf; imagesc(flipud(1-blocks)); axis equal; axis off;
|
||
|
end
|