Related
What my plot looks like
What the plot should look like
The code is working like it should but im trying to get the labels to show up on each line from (1-8). Just like the picture above.
I have read a bunch of posts and tried to search Matlab but i havent been able to figure it out.
clc;clear;close all;
V_inf = 20; % freestream velocity
R = 1; % cylinder radius
n = 8; % number of panels
d_theta = 2*pi/n; % resolution of angles
alpha = 0; % angle of attack
theta = pi+pi/n:-d_theta:-pi+pi/n; % angles of boundary points of panels
X = R*cos(theta); % X coordinates of boundary points of panels
Y = R*sin(theta); % Y coordinates of boundary points of panels
Phi = zeros(n,1); % angle from Vinf to bottom of panel
beta = zeros(n,1); % angle from Vinf to outward normal of panel
conX = zeros(n,1); % X coordinates of control points
conY = zeros(n,1); % Y coordinates of control points
S = zeros(n,1); % panel length
for i = 1:n
Phi(i) = -alpha + atan2((Y(i+1)-Y(i)),(X(i+1)-X(i)));
beta(i) = Phi(i)+pi/2;
if beta(i)>2*pi, beta(i)=beta(i)-2*pi;
elseif beta(i)<0, beta(i)=beta(i)+2*pi; end
conX(i) = (X(i+1)+X(i))/2;
conY(i) = (Y(i+1)+Y(i))/2;
S(i) = sqrt((X(i+1)-X(i))^2 + (Y(i+1)-Y(i))^2);
end
close all
plot(R*cos(0:0.01:2*pi),R*sin(0:0.01:2*pi),'b', X,Y,'r',conX,conY,'g^');
axis equal; legend('Exact shape','Panel approximation','Control points')
xlabel('x, m'); ylabel('y, m'); title('Fig. 1 Panel layout (n = 8, R = 1m)');
Possibly plotting the labels along the points of a circle using the text() function may suffice. There's some shifting of points and flipping that needs to be done to get the order you wish but otherwise it's just 8 points taken along a circle that is smaller in diameter in comparison to the octagon. An alternative would be using the green triangles as reference instead but that involves more math. As long as your octagon is expected to be symmetrical vertically and horizontally this should work alright.
clc;clear;close all;
V_inf = 20; % freestream velocity
R = 1; % cylinder radius
n = 8; % number of panels
d_theta = 2*pi/n; % resolution of angles
alpha = 0; % angle of attack
theta = pi+pi/n:-d_theta:-pi+pi/n; % angles of boundary points of panels
X = R*cos(theta); % X coordinates of boundary points of panels
Y = R*sin(theta); % Y coordinates of boundary points of panels
Phi = zeros(n,1); % angle from Vinf to bottom of panel
beta = zeros(n,1); % angle from Vinf to outward normal of panel
conX = zeros(n,1); % X coordinates of control points
conY = zeros(n,1); % Y coordinates of control points
S = zeros(n,1); % panel length
for i = 1:n
Phi(i) = -alpha + atan2((Y(i+1)-Y(i)),(X(i+1)-X(i)));
beta(i) = Phi(i)+pi/2;
if beta(i)>2*pi, beta(i)=beta(i)-2*pi;
elseif beta(i)<0, beta(i)=beta(i)+2*pi; end
conX(i) = (X(i+1)+X(i))/2;
conY(i) = (Y(i+1)+Y(i))/2;
S(i) = sqrt((X(i+1)-X(i))^2 + (Y(i+1)-Y(i))^2);
end
close all
plot(R*cos(0:0.01:2*pi),R*sin(0:0.01:2*pi),'b', X,Y,'r',conX,conY,'g^');
axis equal; legend('Exact shape','Panel approximation','Control points')
xlabel('x, m'); ylabel('y, m'); title('Fig. 1 Panel layout (n = 8, R = 1m)');
%*************************************************************************%
%ADDING LABELS BY PLOTTING LABELS ALONG CIRCLE%
%*************************************************************************%
Radius = 0.8;
Number_Of_Data_Points = 9;
theta = linspace(0,2*pi,Number_Of_Data_Points);
X_Circle = Radius*cos(theta);
X_Circle = X_Circle(1:end-1);
Y_Circle = Radius*sin(theta);
Y_Circle = Y_Circle(1:end-1);
X_Circle = flip(circshift(X_Circle,3));
Y_Circle = flip(circshift(Y_Circle,3));
for Point_Index = 1: numel(conX)
X_Displacement = X_Circle(Point_Index);
Y_Displacement = Y_Circle(Point_Index);
text(X_Displacement,Y_Displacement,num2str(Point_Index),'HorizontalAlignment','center','fontsize',20);
end
To Plot on Control Points:
%*************************************************************************%
%ADDING LABELS BY PLOTTING LABELS ALONG CONTROL POINTS%
%*************************************************************************%
for Point_Index = 1: numel(conX)
text(conX(Point_Index),conY(Point_Index),num2str(Point_Index),'HorizontalAlignment','center','fontsize',20);
end
How to distribute the points to be like Fig.A
This matlab code for Fig. B :
N = 30; % number of points
r = 0.5; % r = radius
d = 50; % dimension
C_point = 0; % center point
figure, clf
C = ones(1, d) * C_point;
C_rep = repmat( C,N,1);
X = randn(N,d);
s2 = sum(X.^2,2) ;
radius = r * (rand(N,1).^(1/d));
X = X.*repmat(radius./sqrt(s2),1,d) + C_rep;
%% Plot 2D
t = linspace(0, 2*pi, 100);
x = r*cos(t) + C(1);
y = r*sin(t) + C(2);
plot(x,y,'b')
hold on
plot(C(1),C(2),'b.', 'MarkerSize', 10) % center point
hold on
plot(X(:,1), X(:,2),'r.','markersize',10);
axis equal;rotate3d off; rotate3d on;drawnow;shg;
hold on
ax = axis;
Source of the code
What I should change to be like fig. A
The OP's code computes points uniformly distributed within a d-dimensional box, projects those onto a d-dimensional sphere, then samples the radius to move them inside the d-dimensional ball. This is perfect except that the points inside the box, when projected onto the sphere, do not form a uniform distribution on that sphere. If instead you find random points distributed in a Gaussian distribution, you are guaranteed uniform angle distribution.
First compute points with a Gaussian distribution in d dimensions (I do all here with minimal changes to the OP's code):
N = 1000; % number of points
r = 0.5; % r = radius
d = 3; % dimension
C_point = 0; % center point
C = ones(1,d) * C_point;
C_rep = repmat(C,N,1);
X = randn(N,d);
Note that I use randn, not rand. randn creates a Gaussian distribution.
Next we normalize the vectors so the points move to the sphere:
nX = sqrt(sum(X.^2,2));
X = X./repmat(nX,1,d);
These points are uniformly distributed, which you can verify by scatter3(X(:,1),X(:,2),X(:,3)); axis equal and turning the display around (a 2D rendering doesn't do it justice). This is the reason I set d=3 above, and N=1000. I wanted to be able to plot the points and see lots of them.
Next we compute, as you already did, a random distance to the origin, and correct it for the dimensionality:
radius = r * (rand(N,1).^(1/d));
X = X.*repmat(radius,1,d) + C_rep;
X now is distributed uniformly in the ball. Again, scatter3(X(:,1),X(:,2),X(:,3)); axis equal shows this.
However, if you set d=50 and then plot only two dimensions of your data, you will not see the data filling the circle. And you will not see a uniform distribution either. This is because you are projecting a 50-D ball onto 2 dimensions, this simply does not work. You either have to trust the math, or you have to slice the data:
figure, hold on
t = linspace(0, 2*pi, 100);
x = r*cos(t) + C(1);
y = r*sin(t) + C(2);
plot(x,y,'b')
plot(C(1),C(2),'b.', 'MarkerSize', 10) % center point
axis equal
I = all(abs(X(:,3:d))<0.1,2);
plot(X(I,1), X(I,2),'r.','markersize',10);
The I there indexes points that are close to the origin in dimensions perpendicular to the first two shown. Again, with d=50 you will have very few points there, so you will need to set N very large! To see the same density of points as in the case above, for every dimension you add, you need to multiply N by 10. So for d=5 you'd have N=1000*10*10=1e5, and for d=50 you'd need N=1e50. That is totally impossible to compute, of course.
I'm trying to calculate the surface between two circular curves (yellow surface in this picture as simplification) but I'm somehow stuck since I don't have datapoints at the same angular values of the two curves. Any ideas?
Thanks for your help!
Picture:
I assume you have the x,y coordinates which you used to the plot. I obtained them here using imfreehand. I used inpolygon to generate a binary mask for each curve and then apply xor on them to get a mask of the desired area:
% x,y were obtained using imfreehand on 100x100 image and getPosition()
x = [21;22;22;22;22;22;22;23;23;23;23;23;23;24;25;25;26;26;27;28;29;30;30;31;32;32;33;34;35;36;37;38;39;40;41;42;43;44;45;46;47;48;49;50;51;52;53;54;55;56;57;58;59;60;61;62;63;64;65;66;67;68;69;70;71;72;73;74;75;76;77;78;79;79;80;80;81;81;81;82;82;82;82;83;83;83;84;84;85;85;86;86;86;86;86;86;85;84;84;83;82;81;80;79;78;77;76;75;74;73;72;71;70;69;68;67;66;65;64;63;62;61;60;59;58;57;56;55;54;53;52;51;50;49;48;47;46;45;44;43;42;41;40;39;38;37;36;35;34;33;32;31;30;29;28;27;26;25;25;24;24;23;22;21;21;21;21;21;21;21;21;21;21;21;21;21];
y = [44;43;42;41;40;39;38;37;36;35;34;33;32;31;30;29;28;27;26;25;24;23;22;21;20;19;18;18;17;17;17;17;17;16;16;16;16;16;16;15;15;14;14;14;14;14;14;15;15;15;16;16;17;17;17;17;18;18;18;19;20;20;21;22;23;23;24;25;26;27;28;29;30;31;32;33;34;35;36;37;38;39;40;41;42;43;44;45;46;47;48;49;50;51;52;53;54;55;56;56;57;57;58;59;59;60;61;61;61;61;61;60;60;60;59;58;57;56;56;55;55;54;54;54;54;54;54;54;54;54;55;55;55;55;56;57;58;59;60;61;61;62;63;63;64;64;65;65;66;66;66;66;66;66;65;64;63;62;61;60;59;58;57;56;55;54;53;52;51;50;49;48;47;46;45;44];
% generate arbitrary xy
x1 = (x - 50)./10; y1 = (y - 50)./10;
x2 = (x - 50)./10; y2 = (y - 40)./10;
% generate binary masks using poly2mask
pixelSize = 0.01; % resolution
xx = min([x1(:);x2(:)]):pixelSize:max([x1(:);x2(:)]);
yy = min([y1(:);y2(:)]):pixelSize:max([y1(:);y2(:)]);
[xg,yg] = meshgrid(xx,yy);
mask1 = inpolygon(xg,yg,x1,y1);
mask2 = inpolygon(xg,yg,x2,y2);
% add both masks (now their common area pixels equal 2)
combinedMask = mask1 + mask2;
% XOR on both of them
xorMask = xor(mask1,mask2);
% compute mask area in units (rather than pixels)
Area = bwarea(xorMask)*pixelSize^2;
% plot
subplot(131);
plot(x1,y1,x2,y2,'LineWidth',2);
title('Curves');
axis square
set(gca,'YDir','reverse');
subplot(132);
imshow(combinedMask,[]);
title('Combined Mask');
subplot(133);
imshow(xorMask,[]);
title(['XNOR Mask, Area = ' num2str(Area)]);
function area = area_between_curves(initial,corrected)
interval = 0.1;
x = -80:interval:80;
y = -80:interval:80;
[X,Y] = meshgrid(x,y);
in_initial = inpolygon(X,Y,initial(:,1),initial(:,2));
in_corrected = inpolygon(X,Y,corrected(:,1),corrected(:,2));
in_area = xor(in_initial,in_corrected);
area = interval^2*nnz(in_area);
% visualization
figure
hold on
plot(X(in_area),Y(in_area),'r.')
plot(X(~in_area),Y(~in_area),'b.')
end
If I use the lines of the question, this is the result:
area = 1.989710000000001e+03
I'm pretty new to different plots in Matlab and I'm trying to write a code that will show the flow field around a cylinder in Matlab. I'm at the very start and first of all I want to just make the circle in a rectangular domain (cylinder should not be right in the middle of the field).
So far, I have this set up but I want to know if it's possible to make the cylinder look more circular and less like an oval, especially because the domain is a rectangle and not a square. The points on the circle are correct but I want it to look better. Any tips on this? The code I have at the moment is:
U_i = 20; % Ambient velocity
a = 4; % cylinder radius
c = -a*5; % starting coordinate (x)
b = a*10; % ending coordinate (x)
d = -60; % starting coordinate (y)
e = 60; % ending coordinate (y)
n = a*50; % number of intervals (step size in grid)
[x,y] = meshgrid([c:(b-c)/n:b],[d:(e-d)/n:e]');
for i = 1:length(x)
for k = 1:length(x);
f = sqrt(x(i,k).^2 + y(i,k).^2);
if f < a
x(i,k) = 0;
y(i,k) = 0;
end
end
end
% Definition of polar variables
r = sqrt(x.^2+y.^2);
theta = atan2(y,x);
%% Creation of Streamline function
z = U_i.*r.*(1-a^2./r.^2).*sin(theta);%- G*log(r)/(2*pi);
%% Creation of Figure
m = 100;
s = ones(1,m+1)*a;
t = [0:2*pi/m:2*pi];
%% Streamline plot
contour(x,y,z,50);
hold on
polar(t,s,'-k');
% axis square
title('Stream Lines');
grid off
i have to do super resolution of two low resolution images to obtain a high resolution image.
2nd image is taken as base image and the first image is registered with respect to it . i used SURF algorithm for image registration . A Delaunay triangulation is
constructed over the points using a built-in MATLAB delaunay
function . The HR grid of size is
constructed for a prespecified resolution enhancement factor R Then HR algorithm for interpolating the pixel values on the
HR grid is summarized next.
HR Algorithm Steps:
1. Construct the Delaunay triangulation
over the set of scattered vertices in the
irregularly sampled raster formed from the
LR frames.
Estimate the gradient vector at each
vertex of the triangulation by calculating the unit normal vector of neighbouring vector using cross product method.Sum of the unit normal vector of each triangle multiplied by its area is divided by summation of area of all neighbouring triangles to get the vertex normal.
Approximate each triangle patch in
the triangulation by a continuous and,
possibly, a continuously differentiable
surface, subject to some smoothness constraint.
Bivariate polynomials or splines
could be the approximants as explained
below.
Set the resolution enhancement factor
along the horizontal and vertical directions
and then calculate the pixel value
at each regularly spaced HR grid point to
construct the initial HR image
The bivariate polynomial i used is mentioned in the code, using pixel values at each vertex of a triangle and corresponding gradient in x and y directions i calculated the nine constants associated with each triangle then defined a high resolution grid , calculated the pixel values at each point using the constants calculated
i am attaching my code with it, the problem i am facing is that i am just getting a gray image as out put HR image , because the constants i have calculated have negative values resulting in negative pixel values
another problem i realized with my code is in gradient estimation i get a lot of 'NaN' as a result of gradient calculation.
if any one can please spent some time to help me out
close all
clear all
K = 2;
P1 = imread('C:\Users\Javeria Farooq\Desktop\project images\a.pgm');
%reads the image to be registered
P2 = imread('C:\Users\Javeria Farooq\Desktop\project images\b.pgm');
%reads the base image
image1_gray = makelr(P1, 1, 100, 1/2);
%image1_gray = P1;
% makes lr image of first
image2_gray= makelr(P2, 1, 100, 1/2);
%image2_gray= P2;
%makes lr image of second
figure(1),imshow(image1_gray)
axis on;
grid on;
title('Unregistered image');
figure(2),imshow(image2_gray)
axis on;
grid on;
title('Base image ');
impixelinfo
% both image displayed with pixel info
hold on
points_image1= detectSURFFeatures(image1_gray, 'NumScaleLevels', 100, 'NumOctaves', 12, 'MetricThreshold', 500 );
%detects surf features of first image
points_image2 = detectSURFFeatures(image2_gray, 'NumScaleLevels', 100, 'NumOctaves', 12, 'MetricThreshold', 500 );
%detects surf features of second image
[features_image1, validPoints_image1] = extractFeatures(image1_gray, points_image1);
[features_image2, validPoints_image2] = extractFeatures(image2_gray, points_image2);
%extracts features of both images
indexPairs = matchFeatures(features_image1, features_image2, 'Prenormalized', true) ;
% get matching points
matched_pts1 = validPoints_image1(indexPairs(:, 1));
matched_pts2 = validPoints_image2(indexPairs(:, 2));
figure; showMatchedFeatures(image1_gray,image2_gray,matched_pts1,matched_pts2,'montage');
%matched features of both images are displayed
legend('matched points 1','matched points 2');
% Compute the transformation matrix
tform = estimateGeometricTransform(matched_pts1,matched_pts2,'projective')
%calculate transformation matrix using projective transform
T=tform.T;
r=[];
A=[];
l=1
[N1 N2]=size(image2_gray)
registeredPts = zeros(N1*N2,2);
% s= zeros(N1*N2,2);
pixelVals = zeros(N1*N2,1);
[N1 N2]=size(image2_gray)
for row = 1:N1
for col = 1:N2
pixNum = (row-1)*N2 + col;
pixelVals(pixNum,1) = image2_gray(row,col);
registeredPts(pixNum,:) = [col,row];
end
end
[r]=transformPointsForward(tform,registeredPts);
%coordinates of base image
image2_gray=double(image2_gray);
R=2;
r1=r(:,1);
r2=r(:,2);
for row = 1:N1
for col = 1:N2
pixNum = N1*N2 + (row-1)*N2 + col;
pixelVals(pixNum,1) = image1_gray(row,col);
registeredPts(pixNum,:) = [r1(row,1),r2(row,1)];
end
end
% all pixel values are saved in pixelVals
%all registered points are saved first base image then unregistered image
%delaunay triangulation of all coordinates passing x and y coordinates from registered Points
tri = delaunay(registeredPts(:,1),registeredPts(:,2));
figure(3), triplot(tri,registeredPts(:,1),registeredPts(:,2))
save tri
% Estimate the gradient vector at each vertex
[totalTris,three] = size(tri);
[totalPoints,two] = size(registeredPts);
vGradientVecs = zeros(totalPoints,2);
triAreas = zeros(totalTris,1);
triUnitNormals = zeros(totalTris,3);
vUnitNormals = zeros(totalPoints,3);
% 1. Find the unit normal vectors and the areas of all triangles,
% then find the product of these two numbers for each triangle
for triNum = 1:totalTris
v = tri(triNum,:);
% 3D triangle points: x,y,pixel
b=pixelVals(v);
b=b(:);
p = [registeredPts(v,:),b];
% triangle area
triAreas(triNum) = polyarea([p(:,1)],[p(:,2)]);
% directional vectors representing the surface of the plane
d1 = p(2,:)-p(1,:);
d2 = p(3,:)-p(1,:);
% cross product of these vectors
crossp = cross(d1,d2);
% If u = [u1 u2 u3] and v = [v1 v2 v3], we know that the product w is defined as w = [(u2v3 – u3v2) (u3v1 - u1v3) (u1v2 - u2v1)]
% normalized cross product = unit normal vector for the triangle
dist = sqrt(sum(crossp.^2));
triUnitNormals(triNum,:) = crossp./dist;
end
% %2. %Estimate the unit normal vector at each vertex
% a. Find the triangle patches that neighbor the vertex
% b. Find the unit normal vectors of these regions
% c. Multiply each of these vectors by the area of the
% associated region, then sum these numbers and divide
% by the total area of all the regions
for pointNum = 1:totalPoints
[neighbors,x] = find(tri==pointNum);
areas = triAreas(neighbors);
areas3 = [areas,areas,areas];
triNormsSum = sum(triUnitNormals(neighbors,:).*areas3);
triAreasSum = sum(areas);
vUnormalized = triNormsSum./triAreasSum;
vUnitNormals(pointNum,:) = ...
vUnormalized./sqrt(sum(vUnormalized.^2));
if( triAreasSum == 0 )
triAreasSum = 0.0001;
vUnormalized = triNormsSum./triAreasSum;
% re-normalize
vUnitNormals(pointNum,:) = ...
vUnormalized./sqrt(sum(vUnormalized.^2));
end
% 3. Find the gradients along the x and y directions for each vertex
% vertex's unit normal: n = [nx,ny,nz]
% x-direction gradient: dz/dx = -nx/nz
% y-direction gradient: dz/dy = -ny/nz
%
for pointNum = 1:totalPoints
nz = vUnitNormals(pointNum,3);
if( nz == 0 )
nz = 0.0001;
end
vGradientVecs(pointNum,1) = -vUnitNormals(pointNum,1)./nz;
vGradientVecs(pointNum,2) = -vUnitNormals(pointNum,2)./nz;
% end
end
end
% 1. Find the 3 equations for each vertex, and
% place them in c_equations matrix;
% c_equations = [A for vertex 1;
% A for vertex 2; ...
% A for vertex totalPoints]
% c(point,row,:) gives one row from an A matrix
Btotal = zeros(3,totalPoints);
c_equations = zeros(3*totalPoints,3,9);
for pointNum = 1:totalPoints
% % B = [pixVal; x gradient; y gradient] at this vertex
z = pixelVals(pointNum);
B = [z; vGradientVecs(pointNum,1); vGradientVecs(pointNum,2)];
%
% % Compile all B matrices into a vector
Btotal(:,pointNum) = B;
% B = Ac to calculate c which is c=[c1 c2 .....c9]' take invA and
% multiply by B
x = registeredPts(pointNum,1);
y = registeredPts(pointNum,2);
A = [1 x y x^2 y^2 x^3 (x^2)*y x*(y^2) y^3; ...
0 1 0 2*x 0 3*(x^2) 2*x*y y^2 0; ...
0 0 1 0 2*y 0 x^2 2*x*y 3*(y^2)];
% Compile all A matrices into a vector
c_equations(pointNum,1,:) = A(1,:);
c_equations(pointNum,2,:) = A(2,:);
c_equations(pointNum,3,:) = A(3,:);
end
% 2. Find the c values for each triangle patch
c = zeros(totalTris,9);
c9 = zeros(9,9);
for triNum = 1:totalTris
p1 = tri(triNum,1);
p2 = tri(triNum,2);
p3 = tri(triNum,3);
B9 = [Btotal(:,p1); Btotal(:,p2); Btotal(:,p3)];
c9 = [(c_equations(p1,1,:)); (c_equations(p1,2,:)); (c_equations(p1,3,:)); ...
(c_equations(p2,1,:)); (c_equations(p2,2,:));( c_equations(p2,3,:)); ...
(c_equations(p3,1,:)); (c_equations(p3,2,:));( c_equations(p3,3,:))];
C9=squeeze(c9);
c(triNum,:) = pinv(C9)*B9; %linsolve(c9,B9);
end
% xc = findBPolyCoefficients1(tri,registeredPts,pixelVals,vGradientVecs);
% save xc
% % 2. For each point on the HR grid, find the associated triangle patch,
% % extract its c values, and use these values as the coefficients
% % in a bivariate polynomial to calculate the HR pixel value at
% % each grid point (x,y)
[N1,N2]=size(image1_gray);
[totalTris,three] = size(tri);
M = N1*R-1;
N = N2*R-1;
HRimage = zeros(M,N);
HRtriangles = zeros(M,N);
[X,Y] = meshgrid(1:1/R:N2,1:1/R:N1);
% Check all the triangles in order noting in which triangle each HR
% grid point occurs.
for triNum = 1:totalTris
pts = registeredPts(tri(triNum,:),:);
IN = inpolygon(X,Y,pts(:,1),pts(:,2)); % NxM
HRtriangles(ind2sub(size(IN),find(IN==1))) = triNum;
end
% there is a problem with this part of code ,
for y = 1:M % row
for x = 1:N % col
% For testing, average the pixels from the vertices of the
% triangle the HR point is in.
% pix = pixelVals(tri(HRtriangles(x,y),:));
% HRimage(x,y) = (pix(1) + pix(2) + pix(3))/3;
% Extract appropriate set of 9 c values
HRptC = c(HRtriangles(x,y),:);
% Bivariate polynomial
HRimage(x,y) = sum(HRptC.*[1,x,y,x^2,y^2,x^3,(x^2)*y,x*(y^2),y^3]);
g(x,y)=HRimage(x,y);
%changd xy with yx
end
end
% HRimage = estimateGridVals1(tri,registeredPts,R,N1,N2,pixelVals);
% %Estimating Grid values at each patch
% %save HRimage
g(g(:,:)<0)=0;
figure(8),imshow(g,[]);