Precise and smooth curve with Tikz - tikz

I'm trying to draw some curves, but it doesn't work out very well.
what I need
what I get
\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
ticks=none,
xtick distance=1,
ytick distance=1,
axis equal image=true,
grid,
grid style={gray!50},
grid=both,
xlabel={$x$},
ylabel={$y$},
axis lines=middle,
xmin=-4, xmax=9, ymin=-5, ymax=4,
axis x line=center,
axis y line=center,
]
\addplot[thick, smooth] plot coordinates
{
(-3, -1)
(-.5, -3)
(.5, -1.9)
(1.5, -2.8)
(3.5, 1)
(5.5, 3)
(7.5, -1.95)
(8, -1.5)
};
\end{axis}
\end{tikzpicture}
\end{document}
Is it possible to build such smooth curves without adding a large number of points? In the original drawing, you can see several reference points. Is there any way to configure \addplot or any other command?

Using the added information that all those points (except the last one) have zero gradient, Bézier curves seem better suited than a smooth plot.
So, you may achieve this kind of thing...
with this bit of code...
\documentclass[border=2pt]{standalone}
\usepackage{fourier}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}[thick, line cap=round, >=latex, scale=0.5]
% Some constants for the Bezier curve
\def\x{0.5}
\def\u{1.0}
\def\v{0.3}
\def\w{0.1}
% The grid, axes and labels
\draw[thin, gray!20, help lines] (-4.5 ,-4.5) grid (9.5 ,4.5);
\draw[very thick, ->] (-4.5, 0) -- (9.8, 0) node[above] {$x$};
\draw[very thick, ->] (0, -4.5) -- (0, 4.8) node[left] {$y$};
\path (-3, 0) coordinate (x1) node[above] {$-3$}
(0, 0) coordinate (x2) node[below] {$\quad0$}
(1, 0) coordinate (x3)
(8, 0) coordinate (x4) node[below] {$8$}
(0, 1) coordinate (y1) node[right] {$1$};
% ticks are really cumbersome
\draw[very thick] ($(x1)+(0,-\w)$) -- ($(x1)+(0,\w)$);
\draw[very thick] ($(x3)+(0,-\w)$) -- ($(x3)+(0,\w)$);
\draw[very thick] ($(x4)+(0,-\w)$) -- ($(x4)+(0,\w)$);
\draw[very thick] ($(y1)+(-\w,0)$) -- ($(y1)+(\w,0)$);
% Finally, the points...
\path (-3, -1) coordinate (A)
(-.5,-3) coordinate (B)
(.5, -1.9) coordinate (C)
(1.5,-2.8) coordinate (D)
(3.5, 1) coordinate (E)
(5.5, 3) coordinate (F) node[above] {$y=F(x)$}
(7.5,-1.95) coordinate (G)
(8, -1.5) coordinate (H);
% and the line with suitable gradients (after a bit trial and error)
\draw[ultra thick]
(A) ..controls +(\u, 0) and ( $(B) + (-\x, 0)$ )..
(B) ..controls +(\x, 0) and ( $(C) + (-\v, 0)$ )..
(C) ..controls +(\v, 0) and ( $(D) + (-\v, 0)$ )..
(D) ..controls +(\x, 0) and ( $(E) + (-\u, 0)$ )..
(E) ..controls +(\u, 0) and ( $(F) + (-\x, 0)$ )..
(F) ..controls +(\x, 0) and ( $(G) + (-\u, 0)$ )..
(G) ..controls +(\w, 0) and ( $(H) + (-\w,-\v)$ )..
(H);
% two small circles to mark the curve ends
\draw[thin, fill=white] (A) circle (3pt);
\draw[thin, fill=white] (H) circle (3pt);
\end{tikzpicture}
\end{document}

Related

Swift Draw a line from center of one circle to the edge of another

I am trying to draw a UIBezierPath in swift where i can get it to go from the center of a circle to another circles center but what i really want is for the line to stop at the edge of the end circle but at the point where the line would have intersected the circles edge if the line was continuating to the center of the circle and not stopping at the edge.
I need somehow to calculate the intersection point between the line and the circle. how would i be able to do that when the circles are UIImageViews with width and height of 30 (so radius 15) and i now the centers coordinates of the two circles.
I have found a solution.
From the the set of x and y (center of circles) from now called (x, y) and (x2, y2) a vector can be made that is (x2 - x, y2 - y) where x2 - x i will call a and y2 - y i will call b then the distance of the vector can be calculates as sqrt(a^2 + b^2) where the result of i will call dist.
From this a Unit vector can be made with is (a/dist, b/dist) now all i need to do to get my new coordinates for the arrow is (x,y) as starting coordinates and (x2 + ra/dist, y2 + rb/dist) as the end coordinates where r is the radius of the circle at (x2, y2).

How to find points inside, where sphere intersects with cylinder in MATLAB?

I am trying to identify points of sphere that are inside union of both sphere and cylinder, I have generated random points in side a cylinder as below
pts = 3000;
r= 3*((rand(pts,1)).^(1/3));
theta = 2*pi*rand(pts,1);
x= r.*cos(theta);
y= r.*sin(theta);
z=50*rand(size(x));
and generated random points inside a sphere as below
radius=10;
rvals = (2)*rand(pts,1)-(1);
elevation = asin(rvals);
azimuth = 2*pi*rand(pts,1);
radii =(rand(pts,1).^(1/3))*radius;
[point_x,point_y,point_z] = sph2cart(azimuth,elevation,radii);
The result will be as below
I need to find sphere points that is in intersection with cylinder and cylinder points that are in intersection with sphere.
Is there any general method to identify points inside intersection of different volumes ??
Can anyone help me? Thanks in advance,
Manu
Apparently, you have a sphere with center at (0, 0, 0) and radius 10. To check whether points of the cylinder are in the sphere, you can use:
cylinder_in_sphere = (x.^2 + y.^2 + z.^2) < 100
Your cylinder has radius 3 and a height of 50, so to check whether points of the sphere are in the cylinder, you can use:
sphere_in_cylinder = ((points_x.^2 + points_y.^2) < 9) & (points_z >= 0) & (points_z < 50)
Note that in this particular case points_z < 50 is always satisfied, so you can remove it in this particular case.

Find Position based on signal strength (intersection area between circles)

I'm trying to estimate a position based on signal strength received from 4 Wi-Fi Access Points. I measure the signal strength from 4 access points located in each corner of a square room with 100 square meters (10x10). I recorded the signal strengths in a known position (x, y) = (9.5, 1.5) using an Android phone. Now I want to check how accurate can a multilateration method be under the circumstances.
Using MATLAB, I applied a formula to calculate distance using the signal strength. The following MATLAB function shows the application of the formula:
function [ d_vect ] = distance( RSS )
% Calculate distance from signal strength
result = (27.55 - (20 * log10(2400)) + abs(RSS)) / 20;
d_vect = power(10, result);
end
The input RSS is a vector with the four signal strengths measured in the test point (x,y) = (9.5, 1.5). The RSS vector looks like this:
RSS =
-57.6000
-60.4000
-44.7000
-54.4000
and the resultant vector with all the estimated distances to each access points looks like this:
d_vect =
7.5386
10.4061
1.7072
5.2154
Now I want to estimate my position based on these distances and the access points position in order to find the error between the estimated position and the known position (9.5, 1.5). I want to find the intersection area (In order to estimate a position) between four circles where each access point is the center of one of the circles and the distance is the radius of the circle.
I want to find the grey area as shown in this image :
http://www.biologycorner.com/resources/venn4.gif
If you want an alternative way of estimating the location without estimating the intersection of circles you can use trilateration. It is a common technique in navigation (e.g. GPS) to estimate a position given a set of distance measurements.
Also, if you wanted the area because you also need an estimate of the uncertainty of the position I would recommend solving the trilateration problem using least squares which will easily give you an estimate of the parameters involved and an error propagation to yield an uncertainty of the location.
I found an answear that solved perfectly the question. It is explained in detail in this link:
https://gis.stackexchange.com/questions/40660/trilateration-algorithm-for-n-amount-of-points
I also developed some MATLAB code for the problem. Here it goes:
Estimate distances from the Access Points:
function [ d_vect ] = distance( RSS )
result = (27.55 - (20 * log10(2400)) + abs(RSS)) / 20;
d_vect = power(10, result);
end
The trilateration function:
function [] = trilat( X, d, real1, real2 )
cla
circles(X(1), X(5), d(1), 'edgecolor', [0 0 0],'facecolor', 'none','linewidth',4); %AP1 - black
circles(X(2), X(6), d(2), 'edgecolor', [0 1 0],'facecolor', 'none','linewidth',4); %AP2 - green
circles(X(3), X(7), d(3), 'edgecolor', [0 1 1],'facecolor', 'none','linewidth',4); %AP3 - cyan
circles(X(4), X(8), d(4), 'edgecolor', [1 1 0],'facecolor', 'none','linewidth',4); %AP4 - yellow
axis([0 10 0 10])
hold on
tbl = table(X, d);
d = d.^2;
weights = d.^(-1);
weights = transpose(weights);
beta0 = [5, 5];
modelfun = #(b,X)(abs(b(1)-X(:,1)).^2+abs(b(2)-X(:,2)).^2).^(1/2);
mdl = fitnlm(tbl,modelfun,beta0, 'Weights', weights);
b = mdl.Coefficients{1:2,{'Estimate'}}
scatter(b(1), b(2), 70, [0 0 1], 'filled')
scatter(real1, real2, 70, [1 0 0], 'filled')
hold off
end
Where,
X: matrix with APs coordinates
d: distance estimation vector
real1: real position x
real2: real position y
If you have three sets of measurements with (x,y) coordinates of location and corresponding signal strength. such as:
m1 = (x1,y1,s1)
m2 = (x2,y2,s2)
m3 = (x3,y3,s3)
Then you can calculate distances between each of the point locations:
d12 = Sqrt((x1 - x2)^2 + (y1 - y2)^2)
d13 = Sqrt((x1 - x3)^2 + (y1 - y3)^2)
d23 = Sqrt((x2 - x3)^2 + (y2 - y3)^2)
Now consider that each signal strength measurement signifies an emitter for that signal, that comes from a location somewhere at a distance. That distance would be a radius from the location where the signal strength was measured, because one would not know at this point the direction from where the signal came from. Also, the weaker the signal... the larger the radius. In other words, the signal strength measurement would be inversely proportional to the radius. The smaller the signal strength the larger the radius, and vice versa. So, calculate the proportional, although not yet accurate, radius's of our three points:
r1 = 1/s1
r2 = 1/s2
r3 = 1/s3
So now, at each point pair, set apart by their distance we can calculate a constant (C) where the radius's from each location will just touch one another. For example, for the point pair 1 & 2:
Ca * r1 + Ca * r2 = d12
... solving for the constant Ca:
Ca = d12 / (r1 + r2)
... and we can do this for the other two pairs, as well.
Cb = d13 / (r1 + r3)
Cc = d23 / (r2 + r3)
All right... select the largest C constant, either Ca, Cb, or Cc. Then, use the parametric equation for a circle to find where the coordinates meet. I will explain.
The parametric equation for a circle is:
x = radius * Cos(theta)
y = radius * Sin(theta)
If Ca was the largest constant found, then you would compare points 1 & 2, such as:
Ca * r1 * Cos(theta1) == Ca * r2 * Cos(theta2) &&
Ca * r1 * Sin(theta1) == Ca * r2 * Sin(theta2)
... iterating theta1 and theta2 from 0 to 360 degrees, for both circles. You might write code like:
for theta1 in 0 ..< 360 {
for theta2 in 0 ..< 360 {
if( abs(Ca*r1*cos(theta1) - Ca*r2*cos(theta2)) < 0.01 && abs(Ca*r1*sin(theta1) - Ca*r2*sin(theta2)) < 0.01 ) {
print("point is: (", Ca*r1*cos(theta1), Ca*r1*sin(theta1),")")
}
}
}
Depending on what your tolerance was for a match, you wouldn't have to do too many iterations around the circumferences of each signal radius to determine an estimate for the location of the signal source.
So basically you need to intersect 4 circles. There can be many approaches to it, and there are two that will generate the exact intersection area.
First approach is to start with one circle, intersect it with the second circle, then intersect the resulting area with the third circle and so on. that is, on each step you know current intersection area, and you intersect it with a new circle. The intersection area will always be a region bounded by circle arcs, so to intersect it with a new circle you walk along the boundary of the area and check whether each bounding arc intersects with a new circle. If it does, then you leave only the part of the arc that lies inside a new circle, remember that you should continue with an arc from a new circle, and continue traversing the boundary until you find the next intersection.
Another approach that seems to result in a worse time complexity, but in your case of 4 circles this will not be important, is to find all the intersection points of two circles and choose only those points that are of interest for you, that is which lie inside all other circles. These points will be the corners of your area, and then it is rather easy to reconstruct the area. After googling a bit, I have even found a live demo of this approach.

Bargraph Error in Tikzpicture

I don't know why the data on x-axis over leaping. I don't have any idea.
\documentclass[varwidth=true, border=2pt]{standalone} \usepackage{pgfplots}\begin{document}
\begin{tikzpicture}
\begin{axis}[
symbolic x coords={Coke-Classic,Diet Coke, Dr.Peppre,Pepsi Cola,Sprite,},
xtick=data
]
\addplot[ybar,fill=blue] coordinates {
(Coke-Classic, 38)
(Diet Coke, 16)
(Dr.Peppre, 10)
(Pepsi Cola, 26)
(Sprite, 10)
};
\end{axis}
\end{tikzpicture} \end{document}
There are two possible solutions, that came to my mind. Both are relatively easy (only one line has to be added):
Solution 1
To avoid overlapping x-labels, you can explicitly define the size of one x-unit:
\documentclass[varwidth=true, border=2pt]{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
symbolic x coords={Coke-Classic,Diet Coke, Dr.Peppre,Pepsi Cola,Sprite,},
xtick=data,
x=2cm
]
\addplot[ybar,fill=blue] coordinates {
(Coke-Classic, 38)
(Diet Coke, 16)
(Dr.Peppre, 10)
(Pepsi Cola, 26)
(Sprite, 10)
};
\end{axis}
\end{tikzpicture}
\end{document}
The only thing I changed is adding x=2cm to the axis-options.
The result looks as follows:
Solution 2
The solution above increases the width of the plot. If you don't want this, you can instead rotate the tick labels:
\documentclass[varwidth=true, border=2pt]{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
symbolic x coords={Coke-Classic,Diet Coke, Dr.Peppre,Pepsi Cola,Sprite,},
xtick=data,
xticklabel style={rotate=45}
]
\addplot[ybar,fill=blue] coordinates {
(Coke-Classic, 38)
(Diet Coke, 16)
(Dr.Peppre, 10)
(Pepsi Cola, 26)
(Sprite, 10)
};
\end{axis}
\end{tikzpicture}
\end{document}
Here I just replaced the x=2cm with xticklabel style={rotate=45} (45 is the rotation angle, you can use any other angle, just use what you think looks best).

Periodic boundary condition in Matlab for random spheres in a cube model

I have random non-overlapping spheres (stationary) in a cube. I am trying to implement periodic boundary condition on the walls, so that if there are any half sphere on the edge it appears on the other side. This seems to be a well studied problem, but am not sure how should i implement it on spheres.
At the start of the code, i would have random sphere position (c, r), where c = [ x y z] inside or on the edges of cube of dimension (dims), where dims = [ l b h ].
Code for selecting a random sphere in a cube:
function [ c, r ] = randomSphere_1( dims )
% creating one sphere at random inside [0..dims(1)]x[0..dims(2)]x...
% radius and center coordinates are sampled from a uniform distribution
% over the relevant domain.
%
% output: c - center of sphere (vector cx, cy,... )
% r - radius of sphere (scalar)
r = 0.15 + ( 0.55 - 0.15) .* rand(1);% radius varies between 0.15mm - 0.55mm
c = bsxfun (#times,(dims) , rand(1,3)) + r; % to make sure sphere is placed inside or on the edge of the cube
% periodic condition
*if*
I am trying to build a code if the center co-ordinates fall on the edge or over them then there should be periodicity in spheres that is the the other half should be on the other side. I have added an image just to give an idea about what i mean by periodic boundary condition. So the spheres on the edges are exactly how i want. How should i proceed with the problem?