Matlab error: pdelib:initmesh:LargeMesh - matlab

I have a question about Matlab mesh generations:
How do I manage the size ofthe mesh in Matlab?
What can I do to workaround this error?
Error message
Error using message
Error filling holes for pdelib:initmesh:LargeMesh. Floating point numbers are not
allowed as holes. They should be converted to strings.
Error in initmesh (line 135)
fprintf(['\n' message('pdelib:initmesh:LargeMesh', ntg).getString() '\n']);
Error in pdegplot>plotTwoDGeometry (line 112)
[p1,~,t1]=initmesh(g,'hmax',0.1,'init','on', 'MesherVersion','R2013a');
Error in pdegplot (line 73)
hh = plotTwoDGeometry(g.geom, plotEdgeNums, plotSubLabels);
Error in test_ellips_10 (line 102)
pdegplot(model,'EdgeLabels','on','SubdomainLabels','on')
This Error is generated by Matlab R2015b when the following code is run:
% Rectangle R1
R1_x1 = 0;
R1_x2 = 3810;
R1_y1 = 0;
R1_y2 = 6800;
% Rectangle R2
R2_x1 = (3810/4);
R2_x2 = (3*3810/4);
R2_y1 = (6800+3810/4);
R2_y2 = 6800;
% Rectangle R5
R5_x1 = (3810/4);
R5_x2 = (3*3810/4);
R5_y1 = 0;
R5_y2 = -(3810/4);
% Rectangle R3
R3_x1 = (3810/2-75);
R3_x2 = (3810/2+75);
R3_y1 = (6800+3810/4+100);
R3_y2 = (6800+3810/4);
% Rectangle R4
R4_x1 = (3810/2-75);
R4_x2 = (3810/2+75);
R4_y1 = -3810/4;
R4_y2 = -(3810/4+100);
% Ellipse E1
% pdeellip(xc,yc,a,b,phi,label)
E1_xc = 3810/4;
E1_yc = 6800;
E1_a = 3810/4;
E1_b = 3810/4;
E1_phi = 0;
% Ellipse E2
% pdeellip(xc,yc,a,b,phi,label)
E2_xc = 3*3810/4;
E2_yc = 6800;
E2_a = 3810/4;
E2_b = 3810/4;
E2_phi = 0;
% Ellipse E3
% pdeellip(xc,yc,a,b,phi,label)
E3_xc = 3810/4;
E3_yc = 0;
E3_a = 3810/4;
E3_b = 3810/4;
E3_phi = 0;
% Ellipse E4
% pdeellip(xc,yc,a,b,phi,label)
E4_xc = 3*3810/4;
E4_yc = 0;
E4_a = 3810/4;
E4_b = 3810/4;
E4_phi = 0;
model = createpde(1);
% Rectangle is code 3, 4 sides,
% followed by x-coordinates and then y-coordinates
R1 = [3, 4, R1_x1,R1_x2,R1_x2, R1_x1, R1_y1, R1_y1, R1_y2, R1_y2]';
R1 = [3, 4, R1_x1,R1_x2,R1_x2, R1_x1, R1_y1, R1_y1, R1_y2, R1_y2]';
R2 = [3, 4, R2_x1,R2_x2,R2_x2, R2_x1, R2_y1, R2_y1, R2_y2, R2_y2]';
R3 = [3, 4, R3_x1,R3_x2,R3_x2, R3_x1, R3_y1, R3_y1, R3_y2, R3_y2]';
R4 = [3, 4, R4_x1,R4_x2,R4_x2, R4_x1, R4_y1, R4_y1, R4_y2, R4_y2]';
R5 = [3, 4, R5_x1,R5_x2,R5_x2, R5_x1, R5_y1, R5_y1, R5_y2, R5_y2]';
% Ellipse is code 1, center (E1_x,E1_y), First semiaxis length (strictly positive),Second semiaxis length (strictly positive),Angle in radians from x axis to first semiaxis
E1 = [4,E1_xc,E1_yc,E1_a,E1_b,E1_phi]';
E2 = [4,E2_xc,E2_yc,E2_a,E2_b,E2_phi]';
E3 = [4,E3_xc,E3_yc,E3_a,E3_b,E3_phi]';
E4 = [4,E4_xc,E4_yc,E4_a,E4_b,E4_phi]';
% Pad E1 with zeros to enable concatenation with R1
E1 = [E1;zeros(length(R1) - length(E1),1)];
E2 = [E2;zeros(length(R1) - length(E2),1)];
E3 = [E3;zeros(length(R1) - length(E3),1)];
E4 = [E4;zeros(length(R1) - length(E4),1)];
% Combine the shapes into one matrix
geom = [R1,R2,R3,R4,R5,E1,E2,E3,E4];
% Names for the geometric objects
ns = (char('R1','R2','R3','R4','R5','E1','E2','E3','E4'));
ns = ns';
% Set formula
sf = 'R1+R2+R3+R4+R5+E1+E2+E3+E4';
% Create geometry
DL=decsg(geom,sf,ns);
% Check model
% If all elements of 0 geometry is OK
gstat=csgchk(geom);
% Include the geometry in the model
geometryFromEdges(model,DL);
% View geometry
pdegplot(model,'EdgeLabels','on','SubdomainLabels','on')
xlim('auto')
ylim('auto')
axis equal
generateMesh(model,'Hgrad',1.3,'Hmax',10,'Box','on','Init','on','jiggle','on','MesherVersion','R2013a');
pdeplot(model)

Mathwork's support answer that it's a bug of matlab. To fix you need to patch pdeplot:
>>edit pdegplot
edit the line 112
[p1,~,t1]=initmesh(g,'hmax',0.1,'init','on', 'MesherVersion','R2013a');
change it to
[p1,~,t1]=initmesh(g,'init','on', 'MesherVersion','R2013a');

Related

Error in plotting values by time: Error using bar: y values must be numeric or duration arrays

Update
This problem has now been added to the list of Millennium Prize Problems
data:
https://drive.google.com/open?id=1hAisMg233kfEqBSM4htdt77dRl37ce6s
Script
excelTable = readtable('excelfile.xlsx');
T = table2array(excelTable(1:end,3:end));
% S
a1 = T(18,3:end);
b1 = T(17,3:end);
c1 = T(16,3:end);
d1 = T(15,3:end);
e1 = T(14,3:end);
% H
a2 = T(12,3:end);
b2 = T(11,3:end);
c2 = T(10,3:end);
d2 = T(9,3:end);
e2 = T(8,3:end);
% HS
a3 = T(5,3:end);
b3 = T(4,3:end);
c3 = T(3,3:end);
d3 = T(2,3:end);
e3 = T(1,3:end);
% T
t = [1 2 3 4 5];
% Plotted
dates = [cat(3,e1,e2,e3); cat(3,d1,d2,d3); cat(3,c1,c2,c3); cat(3,b1,b2,b3); cat(3,a1,a2,a3)];
plotBarStackGroups(dates,t)
title('excel file')
xlabel('Time')
ylabel('Tail')
legend({'S', 'U/S', 'H','HS'})
legend('Location', 'southoutside')
legend('Orientation','horizontal')
plotBarStackGroups
function [] = plotBarStackGroups(stackData, groupLabels)
NumGroupsPerAxis = size(stackData, 1);
NumStacksPerGroup = size(stackData, 2);
% Count off the number of bins
groupBins = 1:NumGroupsPerAxis;
MaxGroupWidth = 0.65; % Fraction of 1. If 1, then we have all bars in groups touching
groupOffset = MaxGroupWidth/NumStacksPerGroup;
figure
hold on;
for i=1:NumStacksPerGroup
Y = squeeze(stackData(:,i,:));
% Center the bars:
internalPosCount = i - ((NumStacksPerGroup+1) / 2);
% Offset the group draw positions:
groupDrawPos = (internalPosCount)* groupOffset + groupBins;
h(i,:) = barh(Y, 'stacked');
set(h(i,:),'BarWidth',groupOffset);
set(h(i,:),'XData',groupDrawPos);
end
hold off;
set(gca,'YTickMode','manual');
set(gca,'YTick',1:NumGroupsPerAxis);
set(gca,'YTickLabelMode','manual');
set(gca,'YTickLabel',groupLabels);
end
ERROR
Error using bar (line 175) y values must be numeric or duration
arrays.
Error in LS (line 31) plotBarStackGroups(dates,t)
ISSUE
I want the result to BE plotted with respect to time. The values in the arrays should BE changing with time. I cannot convert them to numeric value because they have to BE time.
Response to Sol 1
Changed Code:
function [] = plotBarStackGroups(stackData, groupLabels)
NumGroupsPerAxis = size(stackData, 1);
NumStacksPerGroup = size(stackData, 2);
% Count off the number of bins
groupBins = 1:NumGroupsPerAxis;
MaxGroupWidth = 0.65; % Fraction of 1. If 1, then we have all bars in groups touching
groupOffset = MaxGroupWidth/NumStacksPerGroup;
figure
hold on;
for i=1:NumStacksPerGroup
unixtime=(arrayfun(#(x) posixtime(x), stackData));
Y = squeeze(unixtime(:,i,:));
% Center the bars:
internalPosCount = i - ((NumStacksPerGroup+1) / 2);
% Offset the group draw positions:
groupDrawPos = (internalPosCount)* groupOffset + groupBins;
h(i,:) = barh(Y, 'stacked');
set(h(i,:),'BarWidth',groupOffset);
set(h(i,:),'XData',groupDrawPos);
end
hold
off;
set(gca,'YTickMode','manual');
set(gca,'YTick',1:NumGroupsPerAxis);
set(gca,'YTickLabelMode','manual');
set(gca,'YTickLabel',groupLabels);
end
Result
How I want it
the error message is clear - your Y array is not numeric, so it can't plot. If you set a break point in that line, you can see Y is an array of datetime object.
To convert it to a numeric array, there are a few ways, one way is call function posixtime(). like this
unixtime=(arrayfun(#(x) posixtime(x), stackData));
Y = squeeze(unixtime(:,i,:));
h(i,:) = barh(Y, 'stacked');
now you can plot the stack-bar plot.

Plot equally spaced markers along a spiral

I want to move a red star marker along the spiral trajectory with an equal distance of 5 units between the red star points on its circumference like in the below image.
vertspacing = 10;
horzspacing = 10;
thetamax = 10*pi;
% Calculation of (x,y) - underlying archimedean spiral.
b = vertspacing/2/pi;
theta = 0:0.01:thetamax;
x = b*theta.*cos(theta)+50;
y = b*theta.*sin(theta)+50;
% Calculation of equidistant (xi,yi) points on spiral.
smax = 0.5*b*thetamax.*thetamax;
s = 0:horzspacing:smax;
thetai = sqrt(2*s/b);
xi = b*thetai.*cos(thetai);
yi = b*thetai.*sin(thetai);
plot(x,y,'b-');
hold on
I want to get a figure that looks like the following:
This is my code for the circle trajectory:
% Initialization steps.
format long g;
format compact;
fontSize = 20;
r1 = 50;
r2 = 35;
r3= 20;
xc = 50;
yc = 50;
% Since arclength = radius * (angle in radians),
% (angle in radians) = arclength / radius = 5 / radius.
deltaAngle1 = 5 / r1;
deltaAngle2 = 5 / r2;
deltaAngle3 = 5 / r3;
theta1 = 0 : deltaAngle1 : (2 * pi);
theta2 = 0 : deltaAngle2 : (2 * pi);
theta3 = 0 : deltaAngle3 : (2 * pi);
x1 = r1*cos(theta1) + xc;
y1 = r1*sin(theta1) + yc;
x2 = r2*cos(theta2) + xc;
y2 = r2*sin(theta2) + yc;
x3 = r3*cos(theta3) + xc;
y3 = r3*sin(theta3) + yc;
plot(x1,y1,'color',[1 0.5 0])
hold on
plot(x2,y2,'color',[1 0.5 0])
hold on
plot(x3,y3,'color',[1 0.5 0])
hold on
% Connecting Line:
plot([70 100], [50 50],'color',[1 0.5 0])
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0, 0, 1, 1]);
drawnow;
axis square;
for i = 1 : length(theta1)
plot(x1(i),y1(i),'r*')
pause(0.1)
end
for i = 1 : length(theta2)
plot(x2(i),y2(i),'r*')
pause(0.1)
end
for i = 1 : length(theta3)
plot(x3(i),y3(i),'r*')
pause(0.1)
end
I can't think of a way to compute distance along a spiral, so I'm approximating it with circles, in hopes that it will still be useful.
My solution relies on the InterX function from FEX, to find the intersection of circles with the spiral. I am providing an animation so it is easier to understand.
The code (tested on R2017a):
function [x,y,xi,yi] = q44916610(doPlot)
%% Input handling:
if nargin < 1 || isempty(doPlot)
doPlot = false;
end
%% Initialization:
origin = [50,50];
vertspacing = 10;
thetamax = 5*(2*pi);
%% Calculation of (x,y) - underlying archimedean spiral.
b = vertspacing/(2*pi);
theta = 0:0.01:thetamax;
x = b*theta.*cos(theta) + origin(1);
y = b*theta.*sin(theta) + origin(2);
%% Calculation of equidistant (xi,yi) points on spiral.
DST = 5; cRes = 360;
numPts = ceil(vertspacing*thetamax); % Preallocation
[xi,yi] = deal(NaN(numPts,1));
if doPlot && isHG2() % Plots are only enabled if the MATLAB version is new enough.
figure(); plot(x,y,'b-'); hold on; axis equal; grid on; grid minor;
hAx = gca; hAx.XLim = [-5 105]; hAx.YLim = [-5 105];
hP = plot(xi,yi,'r*');
else
hP = struct('XData',xi,'YData',yi);
end
hP.XData(1) = origin(1); hP.YData(1) = origin(2);
for ind = 2:numPts
P = InterX([x;y], makeCircle([hP.XData(ind-1),hP.YData(ind-1)],DST/2,cRes));
[~,I] = max(abs(P(1,:)-origin(1)+1i*(P(2,:)-origin(2))));
if doPlot, pause(0.1); end
hP.XData(ind) = P(1,I); hP.YData(ind) = P(2,I);
if doPlot, pause(0.1); delete(hAx.Children(1)); end
end
xi = hP.XData(~isnan(hP.XData)); yi = hP.YData(~isnan(hP.YData));
%% Nested function(s):
function [XY] = makeCircle(cnt, R, nPts)
P = (cnt(1)+1i*cnt(2))+R*exp(linspace(0,1,nPts)*pi*2i);
if doPlot, plot(P,'Color',lines(1)); end
XY = [real(P); imag(P)];
end
end
%% Local function(s):
function tf = isHG2()
try
tf = ~verLessThan('MATLAB', '8.4');
catch
tf = false;
end
end
function P = InterX(L1,varargin)
% DOCUMENTATION REMOVED. For a full version go to:
% https://www.mathworks.com/matlabcentral/fileexchange/22441-curve-intersections
narginchk(1,2);
if nargin == 1
L2 = L1; hF = #lt; %...Avoid the inclusion of common points
else
L2 = varargin{1}; hF = #le;
end
%...Preliminary stuff
x1 = L1(1,:)'; x2 = L2(1,:);
y1 = L1(2,:)'; y2 = L2(2,:);
dx1 = diff(x1); dy1 = diff(y1);
dx2 = diff(x2); dy2 = diff(y2);
%...Determine 'signed distances'
S1 = dx1.*y1(1:end-1) - dy1.*x1(1:end-1);
S2 = dx2.*y2(1:end-1) - dy2.*x2(1:end-1);
C1 = feval(hF,D(bsxfun(#times,dx1,y2)-bsxfun(#times,dy1,x2),S1),0);
C2 = feval(hF,D((bsxfun(#times,y1,dx2)-bsxfun(#times,x1,dy2))',S2'),0)';
%...Obtain the segments where an intersection is expected
[i,j] = find(C1 & C2);
if isempty(i), P = zeros(2,0); return; end
%...Transpose and prepare for output
i=i'; dx2=dx2'; dy2=dy2'; S2 = S2';
L = dy2(j).*dx1(i) - dy1(i).*dx2(j);
i = i(L~=0); j=j(L~=0); L=L(L~=0); %...Avoid divisions by 0
%...Solve system of eqs to get the common points
P = unique([dx2(j).*S1(i) - dx1(i).*S2(j), ...
dy2(j).*S1(i) - dy1(i).*S2(j)]./[L L],'rows')';
function u = D(x,y)
u = bsxfun(#minus,x(:,1:end-1),y).*bsxfun(#minus,x(:,2:end),y);
end
end
Result:
Note that in the animation above, the diameter of the circle (and hence the distance between the red points) is 10 and not 5.

matlab mesh2d issue which cant be found

im trying to use mesh2d function according to a guide I read.
for some reason im getting all the time this issue:
Undefined function 'mesh2d' for input arguments of type 'double'.
Error in Try1 (line 88)
[p,t] = mesh2d(allnodes, alledges);
I install mesh2d , according to the guide here:
https://github.com/dengwirda/mesh2d
but for some reason im still getting this issue...
this is my code:(im adding the code so it whould be easier in case im missing something, instead il mark the bad part)
clf
file = 'pattern3';
P = imread('Pattern3.png');
P = P(400:3400, 400:3400);
P = 255 - P*6;
P = 1-im2bw(P);
Nmin = min(size(P));
P = P(1:Nmin, 1:Nmin);
[xg, yg] = meshgrid(1:Nmin, 1:Nmin);
P((xg - Nmin/2).^2 + (yg - Nmin/2).^2 > 0.99*0.25*Nmin^2) = 0;
P = padarray(P, [1 1], 0);
CC = bwconncomp(P);
dtheta = pi/24;
theta = (-pi:dtheta:(pi-dtheta))';
nodeouter = [1.1*cos(theta) 1.1*sin(theta)];
Nnodes = length(nodeouter);
nodelist = (1:Nnodes)';
allnodes = nodeouter;
alledges = [nodelist , mod(nodelist, Nnodes)+1];
for n = 1:CC.NumObjects
%for n = 2:2
newP = zeros(size(P));
newP(CC.PixelIdxList{1,n}(:)) = 1;
newP = filter2(fspecial('average',5),newP);
C = contourc(newP,[0.2 0.2]);
C = C(:,2:end)';
C2 = dpsimplify(C,1);
m = 1;
while m <= length(C2(:,1))
if(C2(m,1) == 1 || C2(m,2) == 1)
C2(m,:) = [];
else
m = m + 1;
end
end
C2 = (C2 - Nmin/2)/(Nmin/2);
C = (C - Nmin/2)/(Nmin/2);
figure(1)
hold all
plot(C2(:,1), C2(:,2))
axis image xy
drawnow
nodeinner = C2;
Nnodeshole = length(nodeinner);
nodelist = (1:Nnodeshole)';
edgelist = [nodelist , mod(nodelist, Nnodeshole)+1];
edgelist = edgelist + Nnodes;
allnodes = [allnodes; nodeinner];
alledges = [alledges; edgelist];
Nnodes = Nnodes + Nnodeshole;
n
end
%%
hdata.fun = #(x,y) 0.05*(1 + ((x.^2 + y.^2)/a^2)).^2;
[p,t] = mesh2d(allnodes, alledges); %%here is the issue!!!!!!!!!!!!!!!!!!!!!!!1
%%
as = 0.5;
for n = 1:length(as)
a = as(n);
h = 0;
x = p(:,1);
y = p(:,2);
z = zeros(size(x));
r = sqrt(x.^2 + y.^2);
phi = atan2(y,x);
theta = atan(r/(a+h));
alpha = 2*theta;
xnew = a*sin(alpha).*cos(phi);
ynew = a*sin(alpha).*sin(phi);
znew = -a*cos(alpha);
p2 = [xnew, ynew, znew];
stlwrite('Test.stl', t, p2)
fv.faces = t;
fv.vertices = p2;
clf
figure(3)
patch(fv, 'FaceColor', [1 1 1], 'EdgeColor', 'black', 'LineWidth', 0.1)
axis equal
axis off
xlim([-a a])
ylim([-a a])
zlim([-a a])
camlight head
view(58,28)
zoom(1.5)
drawnow
end
the photo im trying to use:
I recently completely rewrote MESH2D -- bringing it up-to-date with more recent meshing techniques and MATLAB functionality. It looks like you are trying to use subroutines from old versions of the library.
Based on the updates, the routines you want are refine2 and smooth2 (they build and then optimise a two-dimensional constrained Delaunay triangulation).
I recommend that you have a look at the example code contained in tridemo to see how the updated MESH2D toolbox works.

calfem toolbox MATLAB - displacements not showing on graph

You have to have the calfem toolbox to be able to run this code, so I'm hoping some people do!
I've written some code to try and show the displacements, from applied udls, and I've used
uu = extract(Edof,UU);
but they aren't showing on my figure, can anyone figure out why?
addpath ([cd, '/fem']);
% Constants
E = 180e9;
AB = 39.7e2; IB = 4413e4;
AC = 110e2; IC = 9449e4;
q1 = -15e3; w1 = -10e3; w2 = 5e3;
LX1 = 5; LX2 = 10; LX3 = 15; LX4 = 20;
LY1 = 5; LY2 = 8; LY3 = 9;
% Specify Node Coordinates
nodes = [ 0, 0;
0, LY1;
LX1, LY2;
LX2, LY1;
LX2, LY3;
LX3, LY2;
LX4, LY1;
LX4, 0];
% Specify Elements Nodes
conn = [1,2;
2,3;
2,4;
3,4;
3,5;
4,5;
4,6;
4,7;
5,6;
6,7;
7,8];
Nelem = length(conn);
% Initialise Structural Force/Stiffness Matrices
KK = zeros(8*3);
FF = zeros(8*3,1);
% Define Column and Beam Properties
Cprop = [E, AC, IC];
Bprop = [E, AB, IB];
% Initialise system properties
Edof = zeros(Nelem, 1+6);
Ex = zeros(Nelem, 2);
Ey = zeros(Nelem, 2);
Eq = zeros(Nelem, 2);
Eprop = zeros(Nelem,3);
for ii = 1:Nelem
% Look up nodes of element
node1 = conn(ii,1); node2 = conn(ii,2);
% Work out dof based on node number
dof1 = node1*3 + [-2,-1,0];
dof2 = node2*3 + [-2,-1,0];
% Assign to Edof
Edof(ii,:) = [ii, dof1, dof2];
% Look up coordinate based on node
x1 = nodes(node1,1); y1=nodes(node1,2);
x2 = nodes(node2,1); y2=nodes(node2,2);
% Assign to Ex and Ey
Ex(ii,:) = [x1,x2];
Ey(ii,:) = [y1,y2];
% Decide if the element is column or not
if ii==1||11;
Eprop(ii,:) = Cprop;
elseif ii==2;
Eprop(ii,:) = Bprop;
Eq(ii,:) = [0.515*w1, 0.857*w1];
elseif ii==5;
Eprop(ii,:) = Bprop;
Eq(ii,:) = [0.196*w1, 0.98*w1];
elseif ii==3||8;
Eprop(ii,:) = Bprop;
Eq(ii,:) = [0, q1];
elseif ii==9;
Eprop(ii,:) = Bprop;
Eq(ii,:) = [0.196*w2, 0.98*w2];
elseif ii==10;
Eprop(ii,:) = Bprop;
Eq(ii,:) = [0.515*w1, 0.857*w1];
else
Eprop(ii,:) = Bprop;
end
% assemble system
[KE,FE] = beam2e(Ex(ii,:), Ey(ii,:), Eprop(ii,:), Eq(ii,:));
% Combine structural Stiffness forces
[KK,FF] = assem(Edof(ii,:), KK, KE, FF,FE);
end
% Apply Boundary Conditions
bc = [1,0; 2,0; 3,0; 22,0; 23,0; 24,0];
% Solve System
[UU,RR] = solveq(KK,FF,bc);
figure(1)
% Undisplaced Shape
eldraw2(Ex,Ey,[1,1,1])
% Extract Local Displacements
uu = extract(Edof,UU);
% Plot Displaced Shape
scale = 1e2;
eldisp2(Ex,Ey, uu, [1,2,1], scale);
% Add Scale Bar for 10mm
pltscalb2(scale,[1e-2,6,6],[2]);
% Tidy up Graph
axis([-2,22,0,10])
axis equal
xlabel('X, m'); ylabel('Y, m')
title('Simple Portal Frame - Displacement')

spiral meshgrid in matlab

I'm trying to produce some computer generated holograms by using MATLAB. I used equally spaced mesh grid to initialize the spatial grid, and I got the following image
This pattern is sort of what I need except the center region. The fringe should be sharp but blurred. I think it might be the problem of the mesh grid. I tried generate a grid in polar coordinates and the map it into Cartesian coordinates by using MATLAB's pol2cart function. Unfortunately, it doesn't work as well. One may suggest that using fine grids. It doesn't work too. I think if I can generate a spiral mesh grid, perhaps the problem is solvable. In addition, the number of the spiral arms could, in general, be arbitrary, could anyone give me a hint on this?
I've attached the code (My final projects are not exactly the same, but it has a similar problem).
clc; clear all; close all;
%% initialization
tic
lambda = 1.55e-6;
k0 = 2*pi/lambda;
c0 = 3e8;
eta0 = 377;
scale = 0.25e-6;
NELEMENTS = 1600;
GoldenRatio = (1+sqrt(5))/2;
g = 2*pi*(1-1/GoldenRatio);
pntsrc = zeros(NELEMENTS, 3);
phisrc = zeros(NELEMENTS, 1);
for idxe = 1:NELEMENTS
pntsrc(idxe, :) = scale*sqrt(idxe)*[cos(idxe*g), sin(idxe*g), 0];
phisrc(idxe) = angle(-sin(idxe*g)+1i*cos(idxe*g));
end
phisrc = 3*phisrc/2; % 3 arms (topological charge ell=3)
%% post processing
sigma = 1;
polfilter = [0, 0, 1i*sigma; 0, 0, -1; -1i*sigma, 1, 0]; % cp filter
xboundl = -100e-6; xboundu = 100e-6;
yboundl = -100e-6; yboundu = 100e-6;
xf = linspace(xboundl, xboundu, 100);
yf = linspace(yboundl, yboundu, 100);
zf = -400e-6;
[pntobsx, pntobsy] = meshgrid(xf, yf);
% how to generate a right mesh grid such that we can generate a decent result?
pntobs = [pntobsx(:), pntobsy(:), zf*ones(size(pntobsx(:)))];
% arbitrary mesh may result in "wrong" results
NPNTOBS = size(pntobs, 1);
nxp = length(xf);
nyp = length(yf);
%% observation
Eobs = zeros(NPNTOBS, 3);
matlabpool open local 12
parfor nobs = 1:NPNTOBS
rp = pntobs(nobs, :);
Erad = [0; 0; 0];
for idx = 1:NELEMENTS
rs = pntsrc(idx, :);
p = exp(sigma*1i*2*phisrc(idx))*[1 -sigma*1i 0]/2; % simplified here
u = rp - rs;
r = sqrt(u(1)^2+u(2)^2+u(3)^2); %norm(u);
u = u/r; % unit vector
ut = [u(2)*p(3)-u(3)*p(2),...
u(3)*p(1)-u(1)*p(3), ...
u(1)*p(2)-u(2)*p(1)]; % cross product: u cross p
Erad = Erad + ... % u cross p cross u, do not use the built-in func
c0*k0^2/4/pi*exp(1i*k0*r)/r*eta0*...
[ut(2)*u(3)-ut(3)*u(2);...
ut(3)*u(1)-ut(1)*u(3); ...
ut(1)*u(2)-ut(2)*u(1)];
end
Eobs(nobs, :) = Erad; % filter neglected here
end
matlabpool close
Eobs = Eobs/max(max(sum(abs(Eobs), 2))); % normailized
%% source, gaussian beam
E0 = 1;
w0 = 80e-6;
theta = 0; % may be titled
RotateX = [1, 0, 0; ...
0, cosd(theta), -sind(theta); ...
0, sind(theta), cosd(theta)];
Esrc = zeros(NPNTOBS, 3);
for nobs = 1:NPNTOBS
rp = RotateX*[pntobs(nobs, 1:2).'; 0];
z = rp(3);
r = sqrt(sum(abs(rp(1:2)).^2));
zR = pi*w0^2/lambda;
wz = w0*sqrt(1+z^2/zR^2);
Rz = z^2+zR^2;
zetaz = atan(z/zR);
gaussian = E0*w0/wz*exp(-r^2/wz^2-1i*k0*z-1i*k0*0*r^2/Rz/2+1i*zetaz);% ...
Esrc(nobs, :) = (polfilter*gaussian*[1; -1i; 0]).'/sqrt(2)/2;
end
Esrc = [Esrc(:, 2), Esrc(:, 3), Esrc(:, 1)];
Esrc = Esrc/max(max(sum(abs(Esrc), 2))); % normailized
toc
%% visualization
fringe = Eobs + Esrc; % I'll have a different formula in my code
normEsrc = reshape(sum(abs(Esrc).^2, 2), [nyp nxp]);
normEobs = reshape(sum(abs(Eobs).^2, 2), [nyp nxp]);
normFringe = reshape(sum(abs(fringe).^2, 2), [nyp nxp]);
close all;
xf0 = linspace(xboundl, xboundu, 500);
yf0 = linspace(yboundl, yboundu, 500);
[xfi, yfi] = meshgrid(xf0, yf0);
data = interp2(xf, yf, normFringe, xfi, yfi);
figure; surf(xfi, yfi, data,'edgecolor','none');
% tri = delaunay(xfi, yfi); trisurf(tri, xfi, yfi, data, 'edgecolor','none');
xlim([xboundl, xboundu])
ylim([yboundl, yboundu])
% colorbar
view(0,90)
colormap(hot)
axis equal
axis off
title('fringe thereo. ', ...
'fontsize', 18)
I didn't read your code because it is too long to do such a simple thing. I wrote mine and here is the result:
the code is
%spiral.m
function val = spiral(x,y)
r = sqrt( x*x + y*y);
a = atan2(y,x)*2+r;
x = r*cos(a);
y = r*sin(a);
val = exp(-x*x*y*y);
val = 1/(1+exp(-1000*(val)));
endfunction
%show.m
n=300;
l = 7;
A = zeros(n);
for i=1:n
for j=1:n
A(i,j) = spiral( 2*(i/n-0.5)*l,2*(j/n-0.5)*l);
end
end
imshow(A) %don't know if imshow is in matlab. I used octave.
the key for the sharpnes is line
val = 1/(1+exp(-1000*(val)));
It is logistic function. The number 1000 defines how sharp your image will be. So lower it for more blurry image or higher it for sharper.
I hope this answers your question ;)
Edit: It is real fun to play with. Here is another spiral:
function val = spiral(x,y)
s= 0.5;
r = sqrt( x*x + y*y);
a = atan2(y,x)*2+r*r*r;
x = r*cos(a);
y = r*sin(a);
val = 0;
if (abs(x)<s )
val = s-abs(x);
endif
if(abs(y)<s)
val =max(s-abs(y),val);
endif
%val = 1/(1+exp(-1*(val)));
endfunction
Edit2: Fun, fun, fun! Here the arms do not get thinner.
function val = spiral(x,y)
s= 0.1;
r = sqrt( x*x + y*y);
a = atan2(y,x)*2+r*r; % h
x = r*cos(a);
y = r*sin(a);
val = 0;
s = s*exp(r);
if (abs(x)<s )
val = s-abs(x);
endif
if(abs(y)<s)
val =max(s-abs(y),val);
endif
val = val/s;
val = 1/(1+exp(-10*(val)));
endfunction
Damn your question I really need to study for my exam, arghhh!
Edit3:
I vectorised the code and it runs much faster.
%spiral.m
function val = spiral(x,y)
s= 2;
r = sqrt( x.*x + y.*y);
a = atan2(y,x)*8+exp(r);
x = r.*cos(a);
y = r.*sin(a);
val = 0;
s = s.*exp(-0.1*r);
val = r;
val = (abs(x)<s ).*(s-abs(x));
val = val./s;
% val = 1./(1.+exp(-1*(val)));
endfunction
%show.m
n=1000;
l = 3;
A = zeros(n);
[X,Y] = meshgrid(-l:2*l/n:l);
A = spiral(X,Y);
imshow(A)
Sorry, can't post figures. But this might help. I wrote it for experiments with amplitude spatial modulators...
R=70; % radius of curvature of fresnel lens (in pixel units)
A=0; % oblique incidence by linear grating (1=oblique 0=collinear)
B=1; % expanding by fresnel lens (1=yes 0=no)
L=7; % topological charge
Lambda=30; % linear grating fringe spacing (in pixels)
aspect=1/2; % fraction of fringe period that is white/clear
xsize=1024; % resolution (xres x yres number data pts calculated)
ysize=768; %
% define the X and Y ranges (defined to skip zero)
xvec = linspace(-xsize/2, xsize/2, xsize); % list of x values
yvec = linspace(-ysize/2, ysize/2, ysize); % list of y values
% define the meshes - matrices linear in one dimension
[xmesh, ymesh] = meshgrid(xvec, yvec);
% calculate the individual phase components
vortexPh = atan2(ymesh,xmesh); % the vortex phase
linPh = -2*pi*ymesh; % a phase of linear grating
radialPh = (xmesh.^2+ymesh.^2); % a phase of defocus
% combine the phases with appropriate scales (phases are additive)
% the 'pi' at the end causes inversion of the pattern
Ph = L*vortexPh + A*linPh/Lambda + B*radialPh/R^2;
% transmittance function (the real part of exp(I*Ph))
T = cos(Ph);
% the binary version
binT = T > cos(pi*aspect);
% plot the pattern
% imagesc(binT)
imagesc(T)
colormap(gray)