Matlab join 2 arcs - matlab

I am trying to draw a shape using matlab. Here I need to join arcs. I created arc using following code
circr = #(radius,rad_ang) [radius*cos(rad_ang); radius*sin(rad_ang)]; % Circle Function For Angles In Radians
N = 25; % Number Of Points In Complete Circle
r_angl = linspace(pi/2, 5*pi/4, N); % Angle Defining Arc Segment (radians)
radius = 0.5; % Arc Radius
xy_r = circr(radius,r_angl); % Matrix (2xN) Of (x,y) Coordinates
figure(1)
plot(xy_r(1,:), xy_r(2,:))
axis([-1.25*radius 1.25*radius 0 1.25*radius])
Code generates following output
Now I modified code to draw other arc
circr = #(radius,rad_ang) [radius*cos(rad_ang); radius*sin(rad_ang)]; % Circle Function For Angles In Radians
N = 25; % Number Of Points In Complete Circle
r_angl = linspace(pi/2, 5*pi/4, N); % Angle Defining Arc Segment (radians)
radius = 0.5; % Arc Radius
xy_r = circr(radius,r_angl); % Matrix (2xN) Of (x,y) Coordinates
r_angl1 = linspace(4*pi/4,pi/4); % Angle Defining Arc Segment (radians)
radius1 = 0.1; % Arc Radius
xy_r1 = circr(radius1,r_angl1); % Matrix (2xN) Of (x,y) Coordinates
figure(1)
plot(xy_r(1,:), xy_r(2,:),xy_r1(2,:),xy_r1(1,:))
axis([-1.25*radius 1.25*radius 0 1.25*radius]) % Set Axis Limits
axis equal
This code generates
How can I join both arcs? I need to join them using their end points

Inserting the following lines will joint the end points with lines
hold on;
line([xy_r(1,1) xy_r1(1,end)], [xy_r(2,1) xy_r1(2,end)]);
line([xy_r(1,end) xy_r1(2,1)], [xy_r(2,end) xy_r1(1,1)]);
Together:
figure(1)
plot(xy_r(1,:), xy_r(2,:),xy_r1(2,:),xy_r1(1,:))
hold on;
line([xy_r(1,1) xy_r1(1,end)], [xy_r(2,1) xy_r1(2,end)]);
line([xy_r(1,end) xy_r1(2,1)], [xy_r(2,end) xy_r1(1,1)]);
axis([-1.25*radius 1.25*radius 0 1.25*radius]) % Set Axis Limits
axis equal

Related

Creating a circle in a square grid

I try to solve the following 2D elliptic PDE electrostatic problem by fixing the Parallel plate Capacitors code. But I have problem to plot the circle region. How can I plot a circle region rather than the square?
% I use following two lines to label the 50V and 100V squares
% (but it should be two circles)
V(pp1-r_circle_small:pp1+r_circle_small,pp1-r_circle_small:pp1+r_circle_small) = 50;
V(pp2-r_circle_big:pp2+r_circle_big,pp2-r_circle_big:pp2+r_circle_big) = 100;
% Contour Display for electric potential
figure(1)
contour_range_V = -101:0.5:101;
contour(x,y,V,contour_range_V,'linewidth',0.5);
axis([min(x) max(x) min(y) max(y)]);
colorbar('location','eastoutside','fontsize',10);
xlabel('x-axis in meters','fontsize',10);
ylabel('y-axis in meters','fontsize',10);
title('Electric Potential distribution, V(x,y) in volts','fontsize',14);
h1=gca;
set(h1,'fontsize',10);
fh1 = figure(1);
set(fh1, 'color', 'white')
% Contour Display for electric field
figure(2)
contour_range_E = -20:0.05:20;
contour(x,y,E,contour_range_E,'linewidth',0.5);
axis([min(x) max(x) min(y) max(y)]);
colorbar('location','eastoutside','fontsize',10);
xlabel('x-axis in meters','fontsize',10);
ylabel('y-axis in meters','fontsize',10);
title('Electric field distribution, E (x,y) in V/m','fontsize',14);
h2=gca;
set(h2,'fontsize',10);
fh2 = figure(2);
set(fh2, 'color', 'white')
You're creating a square due to the way you're indexing (see this post on indexing). You've specified the rows to run from pp1-r_circle_small to pp1+r_circle_small and similar for the columns. Given that Swiss cheese is not an option, you're creating a complete square.
From geometry we know that all points within distance sqrt((X-X0)^2 - (Y-Y0)^2) < R from the centre of the circle at (X0,Y0) with radius R are within the circle, and the rest outside. This means that you can simply build a mask:
% Set up your grid
Xsize = 30; % Your case: 1
Ysize = 30; % Your case: 1
step = 1; % Amount of gridpoints; use 0.001 or something
% Build indexing grid for circle search, adapt as necessary
X = 0:step:Xsize;
Y = 0:step:Ysize;
[XX,YY] = meshgrid(X, Y);
V = zeros(numel(X), numel(Y));
% Repeat the below for both circles
R = 10; % Radius of your circle; your case 0.1 and 0.15
X0 = 11; % X coordinate of the circle's origin; your case 0.3 and 0.7
Y0 = 15; % Y coordinate of the circle's origin; your case 0.3 and 0.7
% Logical check to see whether a point is inside or outside
mask = sqrt( (XX - X0).^2 + (YY - Y0).^2) < R;
V(mask) = 50; % Give your circle the desired value
imagesc(V) % Just to show you the result
axis equal % Use equal axis to have no image distortion
mask is a logical matrix containing 1 where points are within your circle and 0 where points are outside. You can then use this mask to logically index your potential grid V to set it to the desired value.
Note: This will, obviously, not create a perfect circle, given you cannot plot a perfect circle on a square grid. The finer the grid, the more circle-like your "circle" will be. This shows the result with step = 0.01
Note 2: You'll need to tweek your definition of X, Y, X0, Y0 and R to match your values.

Map set of points which values represent a radius to a circle with radius R

I have a set of data points that represent a radius. My threshold radius is R. If my data points have a radius < R or a radius > R, I would like to show it visually with Matlab.
I have plotted the circle successfully (using the equation of the circle), but my data points are plotted outside the circle even though their values are less than R. I think I am not properly mapping the data points.
I am doing the following:
%% Circle %%
% Radius = 1;
tx = linspace(-1,1,100); %% X-data
ty = sqrt(1-tx.^2); %% Y-data
ty2 = -ty; %% (-)Y-data
%% Data Points %%
list_radius =[0.5870 0.2077 0.3012 0.4709 1.1524 6.7545 1.5581 1.8074];
%% PLOT %%
plot(tx,ty,':r',tx,ty2,':r')
hold on
plot(list_radius)
hold off
I was expecting to see the points with list_radius < 1 inside the circle and the points with list_radius > 1 outside the circle.
Thanks for your help!
I suggest you plot circles generating x and y points for a circle with x = R·cos(Θ)y = R·sin(Θ) where Theta is a vector from 0 to 2*pi and R is your desired radius. Using this equation you don't have to generate a vector ty2 and you can plot your circle with one plot command.
R = 1;
theta = linspace(0,2*pi,1000);
tx = R*cos(theta);
ty = R*sin(theta);
list_radius =[0.5870 0.2077 0.3012 0.4709 1.1524 6.7545 1.5581 1.8074];
plot(tx,ty,':r');
hold on;
plot(list_radius,zeros(1,numel(list_radius)),'*');
axis equal
With this snippet I assumed your list_radius points lie on the x-axis.

How to plot points on several concentric circles in sequence?

I want to plot several points on several concentric circles just like this:
The number of points on different circles are same and to be determined. The difference of radius are same.
But I face the problem that if I want to use the for function, I define i = 1:total number of points. I don't know how to select correct angle value. Can anyone help me?
Here is the code that I wrote:
R_steplength = 1; %difference of radius
angle_point = 20; %total number of points on one circle
max_R = 4; %outer radius of circle
central_x = 1; % origin of concentric circle
central_y = 1;
total_circle_points = (max_R/R_steplength) * angle_point; %calculate total
points
fin_x= zeros(1, total_circle_points); %define output points position
fin_y = zeros(1, total_circle_points);
for i = 1:total_circle_points
for j = 1:angle_point
if rem(i+1, 20)~= 1
k = floor(i/20);
angles = linspace(0,2*pi,angle_point);
fin_x(i) = R_steplength*(k+1)*cos(angles(j))+central_x;
fin_y(i)= R_steplength*(k+1)*sin(angles(j))+central_y;
else
fin_x(i) = central_x + R_steplength*(k+2);
fin_y(i) = central_y + R_steplength*(k+2);
end
plot(fin_x(:),fin_y(:),'ro')
end
end
You can use polarplot for that:
ax = polaraxes; % create polar axes
% calculate all points locations:
[angles,rad] = meshgrid(0:angle_point:360,1:R_steplength:max_R);
polarplot(ax,deg2rad(angles),rad,'r.') % plot all the points
ax.GridColor = 'k'; % set grid color to black
ax.GridAlpha = 1;
ax.ThetaAxis.TickValues = 10:20:360; % set radius grid between the points
ax.RAxis.TickValues = 1.5:R_steplength:(max_R+0.5); % set circles between the points
ax.RAxis.Limits = [0 max_R+0.5]; % show the outer circle
Here I use the axes grid to draw the circles. If this is not needed you can just write:
[angles,rad] = meshgrid(0:angle_point:360,1:R_steplength:max_R);
polarplot(ax,deg2rad(angles),rad,'r.') % plot all the points

MATLAB - Rotating an equilateral triangle around its centre point

I am new to MATLAB, but have worked with javascript and other programming languages.
I am writing a MATLAB program that will generate an equilateral triangle given the side length, an x coordinate, a y coordinate and an angle of rotation. It is working as intended except for the rotations.
I am using a rotation matrix to rotate the triangle. This works, except it rotates around the origin instead of rotating on the spot. (see below example).
90 degree Rotations Example
In order to rotate it on the spot I think I need to calculate the centre of the triangle and then rotate around that(somehow). I am not sure how to do this or if there is an easier/better way to do this. I did see there is a rotate function, but from what I have seen, it is for spherical space, not Cartesian planes.
Code is below, sorry for the mess:
function [ side, coord1,coord2 ] = equilateral(side, x,y, rotation)
%EQUILATERAL- given a side length and x,y, coordinates as inputs, the
%function plots an equilateral triangle an angle of rotation can be
%given as an input as well. This will rotate the trianlge around the x
%and y coordinates given.
%rotation argument is not required. If not given, angle is 0
if(exist('rotation','var'))
angle = rotation;
else
angle = 0;
end
%rotation matrix
R = [cos(angle), -sin(angle); sin(angle), cos(angle)];
%Make the axis equal so the triangles look equilateral
axis equal;
%max horizontal x coordinate
x2 = x + side;
%max horiontal y coordinate (equal to original y coordinate)
y2 = y;
%height of the triangle at midpoint (perpendicular height)
h = side*sin(pi/3) + y;
%coordinates of midpoint/top vertice
mid = [x2-(0.5*side), h];
%min coordinates
coord1 = [x,y];
%max coordinates
coord2 = [x2,y2];
if (angle > 0)
coord1 = coord1*R;
coord2 = coord2*R;
mid = mid*R;
end
%plot the base of the triangle
plot(linspace(coord1(1),coord2(1)), linspace(coord1(2),coord2(2)));
hold on
%plot the first side from inital coords to midpoint
plot(linspace(coord1(1),mid(1)), linspace(coord1(2),mid(2)));
%plot second side from mid point to max coords
plot(linspace(mid(1),coord2(1)), linspace(mid(2),coord2(2)));
end
I am open to any suggestions for improvements to the code/help to clean it up as well as help with the rotation issues. Thanks for the help.
The rotation matrix
[cos(theta), -sin(theta)
sin(theta), cos(theta)]
rotates a set of points of an angle theta about the origin of the axes.
In order to rotate a point around a given point, you have to:
-shift your points so that the rotatioin point concides with the origin of the axes
- rotate the point using the rotation matrix
- shift back your points
The following code is a modified version of your function in which the proposed approach has been implemented.
In the code I've set the rotation point as the centre of gravity
XR=x+side/2
YR=y+h*.3
nevertheless, you can compute them in a different way.
function [ side, coord1,coord2 ] = equilateral(side, x,y, rotation)
%EQUILATERAL- given a side length and x,y, coordinates as inputs, the
%function plots an equilateral triangle an angle of rotation can be
%given as an input as well. This will rotate the trianlge around the x
%and y coordinates given.
%rotation argument is not required. If not given, angle is 0
if(exist('rotation','var'))
% angle = rotation;
% Convert the angle from deg to rad
angle = rotation*pi/180;
else
angle = 0;
end
%rotation matrix
R = [cos(angle), -sin(angle); sin(angle), cos(angle)];
%Make the axis equal so the triangles look equilateral
axis equal;
%max horizontal x coordinate
x2 = x + side;
%max horiontal y coordinate (equal to original y coordinate)
y2 = y;
%height of the triangle at midpoint (perpendicular height)
h = side*sin(pi/3) + y;
%coordinates of midpoint/top vertice
mid = [x2-(0.5*side), h];
%min coordinates
coord1 = [x,y];
%max coordinates
coord2 = [x2,y2];
plot([coord1(1) coord2(1) mid(1) coord1(1)],[coord1(2) coord2(2) mid(2) coord1(2)],'r')
hold on
%
% Define the coord of the point aroud with to turn
%
XR=x+side/2
YR=y+h*.3
plot(XR,YR,'o','markerfacecolor','k','markeredgecolor','k')
if (angle > 0)
% coord1 = coord1*R;
% coord2 = coord2*R;
% mid = mid*R;
% Shift the triangle so that the rotation point coincides with the origin
% of the axes
r_coord1 = (coord1-[XR YR])*R+[XR YR];
r_coord2 = (coord2-[XR YR])*R+[XR YR];
r_mid = (mid-[XR YR])*R+[XR YR];
%
% Plot the rotated triangle
plot([r_coord1(1) r_coord2(1) r_mid(1) r_coord1(1)],[r_coord1(2) r_coord2(2) r_mid(2) r_coord1(2)],'r')
end
% % %
% % % %plot the base of the triangle
% % % plot(linspace(coord1(1),coord2(1)), linspace(coord1(2),coord2(2)));
% % % hold on
% % % %plot the first side from inital coords to midpoint
% % % plot(linspace(coord1(1),mid(1)), linspace(coord1(2),mid(2)));
% % % %plot second side from mid point to max coords
% % % plot(linspace(mid(1),coord2(1)), linspace(mid(2),coord2(2)));
end
I've also made a couple of additional modification:
I've added a conversion of the input angle from deg to rad; you can discard it if you assume the input is already in rad
I've updated the way to plot the triangle.
As a suggestion, you can use nargin to thest the number of input to your function and varargin to inspect them instead of testing in they exist.
Hope this helps.
Qapla'

Plotting too slow on Matlab

I am having some issues with a code I am writing, simply because it is too long to plot. What I am trying to do is for matlab to plot a series of ellipses filled with colors depending on a specific parameter.
Here is the code I am using:
clearvars -except data colheaders
close all
clc
data(:,15)=data(:,9)*pi/180; % Convers Column 9 (angle of rotation) in rad
data(:,16)=1196-data(:,6); % Reset the Y coordinate axis to bottom left
delta = 0 : 0.01 : 2*pi; % Converts roation angle in rad
theta=45*pi/180; % Sample cutting angle
imax=5352; % Numbers of rows in data sheet
% Define variables for colors
beta=acos(data(1:imax,8)./data(1:imax,7));%./acos(0);
phi=atan(sin(beta).*cos(data(1:imax,15))./(sin(theta)*sin(beta).*sin(data(1:imax,15))+cos(theta)*cos(beta)))/(pi/2);
phi2=phi/2+1/2; % Set phi within 0 and 1 for colormap
gamma=atan((cos(theta)*sin(beta).*sin(data(1:imax,15))-sin(theta)*cos(beta))./...
(sin(theta)*sin(beta).*sin(data(1:imax,15))+cos(theta)*cos(beta)))/(pi/2);
gamma2=gamma+1/2; % Set gamma between 0 and 1 for colormap
cm = colormap(jet) ; % returns the current color map
% Sort and get their index to access the color array
[~,idx] = sort(phi);
for i=1:imax
x = data(i,7)/2 * cos(delta) * cos(data(i,15)) - data(i,8)/2 * sin(delta) * sin(data(i,15)) + data(i,5);
y = data(i,8)/2 * sin(delta) * cos(data(i,15)) + data(i,7)/2 * cos(delta) * sin(data(i,15)) + data(i,16);
colorID1 = max(1, sum(phi2(i) > [0:1/length(cm(:,1)):1]));
colorID2 = max(1, sum(gamma2(i) > [0:1/length(cm(:,1)):1]));
ColorMap1(i,:) = cm(colorID1, :); % returns your color
ColorMap2(i,:) = cm(colorID2, :); % returns your color
hold on
% Columns (5,6) are the centre (x,y) of the ellipse
% Columns (7,8) are the major and minor axes (a,b)
% Column 9 is the rotation angle with the x axis
figure(1);
fill(x,y,ColorMap1(i,:),'EdgeColor', 'None');
title('Variation of In-plane angle \phi')
colorbar('SouthOutside')
grid on;
caxis([-90 90])
%text(data(i,5),data(i,16),[num2str(0.1*round(10*acos(0)*180*phi(i)/pi))])
figure(2);
fill(x,y,ColorMap2(i,:),'EdgeColor', 'None');
title('Variation of Out-of-plane angle \gamma')
colorbar('SouthOutside')
grid on;
caxis([-45 45])
%text(data(i,5),data(i,16),[num2str(0.1*round(10*acos(0)*180*gamma(i)/pi))])
% Assigns angle data to each ellipse
end
axis equal;
Maybe someone knows how to make that it doesnt take ages to plot ( i know figure is a bad method, but I want 2 specific colormap for the 2 variables phi and gamma).
Cheers guys
Example data you can use to run the code
data(:,5) = [3 ;5 ;12; 8]; % Centre location X
data(:,6) = [1; -5 ;-2; 4]; % Centre location Y
data(:,7) = [6 ;7;8;9]; % Major Axis a
data(:,8) = [2;3;3;5]; % Minor axis b
data(:,9) = [10;40;45;90]; % Angle of rotation
All you need to do is change imax for 4 instead of 5352 and it should work
Dorian