I have three points a,b,c whose x,y,z coordinates are
a=[ -0.3519052 0 0];
b=[ 0 -0.674984 0];
c=[ 0 0 -0.6485047];
how do plot a plane(triangle) using these three points in scilab
plot3d and plo3d1 are not giving the form i am looking for.
I figured out the problem!
plot3d1 needs column vectors.
plot3d1(a',b',c')
produced the plot
how to plot triangle in scilab
Plot a triangle using its sides
Consider the fist vertex lies at origin(0,0)
Second vertex lies on X-Axis at (a,0)
From distance formula of triangle
ie.
length of side = sqrt( (x2−x1)^2+(y2−y1)^2 )
Program to Plot a Triangle when sides are given is as below in scilab :
clf()
//Length of the sides
a = 10;
b = 10
c = 10
//Vertex of third point
xc=(a^2-(b^2-c^2))/(2*a)
yc=sqrt(c^2-xc^2);
clf()
x=[0,0,xc]
y=[0,yc,0]
plot2d(0,0,-1,"010","",[0,0,0,0]);
xpoly(x,y,"lines",1)
Related
In a 3D space (x,y,z), you are given two points with no restrictions.
Let's say Point 1 = (15,10,-5), Point 2 = (-1, 0, 11)
An arbitrary point (denoted X in the image) is made by finding the mid-point between point 1 and point 2, in this case (7,5,6), and then y is incremented by 10 which creates a third point
Point 3 = (7,15,6)
Attached is an image to better portray these points
The problem is to find an equation that creates the orange line that links the points 1, 2 and 3. The line doesn't necessarily have to link on the bottom, but I assume it is easier to create an ellipse with these points than an inverse parabola.
It is rather simple to build a circle through these three points (note they must be non-collinear).
Make a plane containing given points, use arbitrary coordinate system in this plane. For example, point P1 is origin, vector P2-P1 defines OX axis, vector product of P2-P1 and P3-P1 defines normal N, and (P2-P1) x N defines OY axis
Solve "circle through three points" problem in this plane, find radius and center.
Transform center back into 3D.
Also note that there is infinite number of ellipses and parabolas through three points (until we define additional limitations),
I have a set of points and a set of line segments. I would like to split the set of points into subsets or clusters based on these line segments. Ultimately I am looking the the convex hull for each subset (the orange polygon shown in the figure on the right). Although the line segments in the example below are connected with one another, this is not always the case. I am guessing that the method should construct a convex hull from all points (orange polygon shown on the left), and then split the convex hull at the intersection point with the line segments, and somehow include the "inner" points in the new convex hulls (ie. points 1,2,3 and 4 in example below).
points = [-0.1325 -2.2267; -0.1525 -2.2267; -0.5319 1.0698; -1.3628 -0.1296; 1.7438 1.3784; 1.5770 0.9458; 0.5147 -2.6114; 0.8169 -2.2797; -1.0244 2.7143; -0.4422 2.8257; -1.7421 -2.4453; -2.4492 -0.4012]
linesegments = [-1.1258 -4.2270 -0.7196 -3.9662; -0.7196 -3.9662 0.4347 -0.4873; -2.3293 1.4275 -3.3717 2.2654; -2.3293 1.4275 0.4347 -0.4873; 1.3579 3.1700 3.3566 0.5079; 3.3566 0.5079 0.4347 -0.4873] % Each row is line with format [x1 y1 x2 y2];
In this example there are 12 points and 6 line segments. Points 1 and 2 are positioned fairly close, but point 2 is slightly to the left and point 1 is slightly to the right. The convex hull of each subsets is:
ch1 = [9 10 5 6 3 9];
ch2 = [12 4 2 11 12];
ch3 = [1 8 7 1];
Start with any point. Label as A. Iterate over all neighbors. If you can reach the neighbor, label it as A, too. Proceed with the next point labeled A (unless it is exactly on a line). Once you have processed all A points, that part is complete. Start B on an unlabeled point.
Compute convex hulls afterwards.
Construct lines between every pair of points. Find the intersection between these lines and the line segments (below I used lineSegmentIntersect). Disregard the pairs of points that intersect any of the line segments. Construct an undirected graph from the remaining pairs of points. Find the connected components in the undirected graph (below I used conncomp which is based on Dulmage-Mendelsohn decomposition). And finally compute the convex hull from the points in each connected component.
This Matlab function convhullc(points, linesegments) will find the coordinates of each convex hull.
function C = convhullc(pp, ll)
np = size(pp,1); % Number of points
% Create line between all pairs of points
combi = nchoosek(1:np, 2);
ppxy = [pp(combi(:,1),:) pp(combi(:,2),:)];
% Intersection between all lines and all line segments
intersectpl = lineSegmentIntersect( ppxy, ll )
% Pairs of points that do not intersect a line segment
nointersect = (sum(intersectpl.intAdjacencyMatrix,2) == 0);
% Creating adjacency matrix of points with no intersect
adj = sparse(combi(nointersect,1), combi(nointersect,2), 1, np, np);
% Create undirected graph
adj = adj + adj.'; %'
% Find the connected components
[nch, bin] = conncomp(adj);
% Find the convex hulls
ch = cell(nch,1);
for i=1:nch
if( sum((bin==i)) > 2 )
ppx = pp((bin==i),1);
ppy = pp((bin==i),2);
K = convhull(ppx, ppy);
ch{i} = [ppx(K) ppy(K)];
end
end
ch = ch(~cellfun('isempty',ch));
C = ch;
end
Graph Visualization represented in a Circle: How To
I am trying to represent a plotted graph line around a circle.
Where the center is 0
Intervals of 45 degrees / 8 values.
Greatest value = 1 / outer boundary of circle.
I want to plot the graph at each interval
Points at right angles are straight forward
I could hack this pretty easy but I'd rather know the math in case I ever want to do more complex things.
I am looking for the math to figure out where the 45 degree increments should be. For example: if the point is .33 of 1 then how do I know where it will be at 45 degrees or at 13 degrees, etc. etc.
Why Lua?
I'm coding in lua so that would be the perferable
EDIT: Made a picture but I don't have enough rep :(
Bar 1 # 0 Deg = Lenght of 1 = x,y of 0,1
Bar 2 # 45 Deg = Lenght of .33 = x,y of ?,?
Bar 3 # 90 Deg = Lenght of .5 = x,y of .5,0
Bar 4 # 105 Deg = Lenght of .66 = x,y of ?,?
How do I get the x,y of Bar 2 and Bar 4?
The easiest way is with polar coordinates where:
x = r cos φ and y = r sin φ
(r would be your length and φ would be your angle)
The one wrinkle is that in polar coordinates, φ = 0 is along the positive x-axis and increasing angles rotate counter-clockwise. To account for the offset in 0° we just subtract 90° from your desired angle. Then to change the rotation to clockwise, we just take the negative of the result. So,
phi = -(angle - 90)
x = length * cos(phi)
y = length * sin(phi)
For your current problem with only 8 angles you could calculate these by hand pretty readily knowing that both cos and sin of 45° is about 0.707.
I have the intrisic and extrinsic parameters of the camera.
The extrinsic is a 4 x 4 matrix with rotation and translation.
I have sample data as under, I have this one per camera image taken.
2.11e-001 -3.06e-001 -9.28e-001 7.89e-001
6.62e-001 7.42e-001 -9.47e-002 1.47e-001
7.18e-001 -5.95e-001 3.60e-001 3.26e+000
0.00e+000 0.00e+000 0.00e+000 1.00e+000
I would like to plot the image as given on the Matlab calibration toolkit page or
However I'm unable to figure out the Math of how to plot these 2 images.
The only lead I have is from this page http://en.wikipedia.org/wiki/Camera_resectioning. Which tells me that the camera position can be found by C = − R` . T
Any idea how to achieve this task?
Assume the corners of the plane that you want to draw are 3x1 column vectors, a = [0 0 0]', b = [w 0 0]', c = [w h 0]' and d = [0 h 0]'.
Assume that the calibration matrix that you provide is A and consists of a rotation matrix R = A(1:3, 1:3) and a translation T = A(1:3, 4).
To draw the first view
For every pose A_i with rotation R_i and translation T_i, transform each corner x_w (that is a, b, c or d) of the plane to its coordinates x_c in the camera by
x_c = R_i*x_w + T_i
Then draw the plane with transformed corners.
To draw the camera, its centre of projection in camera coordinates is [0 0 0]' and the camera x axis is [1 0 0]', y axis is [0 1 0]' and z axis is [0 0 1]'.
Note that in the drawing, the camera y-axis is pointing down, so you might want to apply an additional rotation on all the computed coordinates by multiplication with B = [1 0 0; 0 0 1; 0 -1 0].
Draw the second view
Drawing the plane is trivial since we are in world coordinates. Just draw the plane using a, b, c and d.
To draw the cameras, each camera centre is c = -R'*T. The camera axes are the rows of the rotation matrix R, so for instance, in the matrix you provided, the x-axis is
[2.11e-001 -3.06e-001 -9.28e-001]'. You can also draw a camera by transforming each point x_c given in camera coordinates to world coordinates x_w by x_w = R'*(x_c - T) and draw it.
There is now an example in opencv for visualizing the extrinsics generated from their camera calibration example
It outputs something similar to the original questions ask:
I have two squares, S1 = (x1,y1,x2,y2) and S2 = (a1,b1,a2,b2)
I'm looking for the A transformation matrix with which
A * S1 = S2
As far as I see, A is an affine 3x3 matrix, so I have 9 unknown values.
How can I calculate these values?
thanks and best,
Viktor
There are really only four unknown values here. A rotation angle, a scale factor and an x and y translation. Of your three by three matrix the bottom row is always 0,0,1 which reduces you to six unknowns. The right hand column will be Tx,Ty,1 which are your translations (and the 1 we already know about).
The two by two "matrix" left will be your rotation and scaling. This will (off the top of my head) be something like:
ACos(B), -Asin(B)
ASin(B), aCos(B)
So in total:
ACos(B), -Asin(B), Tx
ASin(B), ACos(B), Ty
0 , 0 , 1
You extend your co-ordinate matrices with the 1 on the end of each co-ordinate to give 2x3 matrices and they then multiply to give you the four equations you need to solve for the four variables. That is left as an exercise for the reader.
A transformation matrix is a factor of scaling matrix Ss, transition matrix St and rotation matrix Sr.
Assume the old point is Po is (Xo,Yo) and as vector will be represented as (Xo Yo 1)' same for the new point Pn
Then Pnv =SsStSrPov
Where Sx is
Sx 0 0
0 Sy 0
0 0 1
St is
1 0 Tx
0 1 Ty
0 0 1
Sr is
Cos(th) -Sin(th) 0
Sin(th) Cos(th) 0
0 0 1
Now back to your question. if two point are giving to represent a rectangle we can just find the parameter of two matrix and the third one will be an identity matrix.
Rect1 is represented as Top-Left point P11 and Bottom-Right Point P12
Rect2 is represented as Top-Left point P21 and Bottom-Right Point P22
S=Ss*St
Sx 0 Tx
0 Sy Ty
0 0 1
Now you have 4 missing parameters and 4 set of equations
P21=S*P11
P22=S*P12
X[P21] =Sx*X[P11]+Tx
Y[P21] =Sy*Y[P11]+Ty
X[P22] =Sx*X[P12]+Tx
Y[P22] =Sy*Y[P12]+Ty
Solve it and you'll get your answer.
and if you have transition and rotation then
S=Sr*St.
Cos(th) -Sin(th) Tx
Sin(th) Cos(th) Ty
0 0 1
Now you have 3 missing parameters and 4 set of equations
P21=S*P11
P22=S*P12
X[P21] =Cos(th)*X[P11]-Sin(th)*Y[P11]+Tx
Y[P21] =Sin(th)*X[P11]+Cos(th)*Y[P11]+Ty
X[P22] =Cos(th)*X[P11]-Sin(th)*Y[P12]+Tx
Y[P22] =Sin(th)*X[P11]+Cos(th)*Y[P12]+Ty
Replace Cos(th) with A and Sin(th) With B and solve the equations.
X[P21] =A*X[P11]-B*Y[P11]+Tx
Y[P21] =B*X[P11]+A*Y[P11]+Ty
X[P22] =A*X[P11]-B*Y[P12]+Tx
Y[P22] =B*X[P11]+A*Y[P12]+Ty
Check if its correct A^2+B^2 =? 1 if is true then th = aCos(A)
The last part of the solution, if you'll have all three matrixes, then S=SrStSs is
Sx*sin(th) -Sx*cos(th) Tx
Sy*cos(th) Sy*sin(th) Ty
0 0 1
Now we have 5 missing variables and we need 6 different set of equations to solve it. which is mean 3 points from each rectangle.
You shouldn't have a 3x3 matrix if you're just looking to transform a 2D object. What you're looking for is a 2x2 matrix that solves A*S1=S2. This can be done in many different ways; in MATLAB, you'd do a S2/S1 (right matrix division), and generally this performs some kind of Gaussian elimination.
How can I calculate these values?
When applied to 2d/3d transformations, matrix can be represented a coordinate system, unless we are talking about projections.
Matrix rows (or columns, depending on notation) form axes of a new coordinate system, in which object will be placed placed if every object vertex is multiplied by the matrix. Last row (or columne, depending on notation) points to the center of the new coordinate system.
Standard OpenGL/DirectX transformation matrix (NOT a projection matrix):
class Matrix{//C++ code
public:
union{
float f[16];
float m[4][4];
};
};
Can be represented as combination of 4 vectors vx (x axis of the new coordinate system), vy(y axis of a new coordinate system), vz(z axis of a new coordinate system), and vp (center of the new system). Like this:
vx.x vx.y vx.z 0
vy.x vy.y vy.z 0
vz.x vz.y vz.z 0
vp.x vp.y vp.z 1
All "calculate rotation matrix", "calculate scale matrix", etc go down to this idea.
Thus, for 2d matrix, you'll have 3x3 matrix that consists of 3 vectors - vx, vy, vp, because there is no z vector in 2d. I.e.:
vx.x vx.y 0
vy.x vy.y 0
vp.x vp.y 1
To find a transform that would transform quad A into quad B, you need to find two transforms:
Transform that will move quad A into origin (i.e. at point zero), and convert it into quad of fixed size. Say, quad (rectangle) whose one vertex x = 0, y = 0, and whose vertices are located at (0, 1), (1, 0), (1, 1).
Transform that turns quad of fixed size into quad B.
You CANNOT do that it this way if opposite edges of quad are not parallel. I.e. parallelograms are fine, but random 4-sided polygons are not.
A quad can be represented by base point (vp) which can be any vertex of the quad and two vectors that define quad sizes (direction of the edge multiplied by edge's length). I.e. "up" vector and "side" vector. Which makes it a matrix:
side.x side.y 0
up.x up.y 0
vp.x vp.y 1
So, multiplying a quad (vp.x = 0, vp.y = 0, side.x = 1, side.y = 0, up.x = 0, up.y = 1) by this matrix will turn original quad into your quad. Which means, that in order to transform
quad A into quad B, you need to do this:
1) make a matrix that would transform "base 1unit quad" into quad A. Let's call it matA.
2) make a matrix that would transform "base 1 unit quad" into quad B. let's call it matB.
3) invert matA and store result into invMatA.
4) the result matrix is invMatA * matB.
Done. If you multiply quad A by result matrix, you'll get quad B. This won't work if quads have zero widths or heights, and it won't work if quads are not parallelograms.
This is hard to understand, but I cannot to make it simpler.
What do you mean by S1 = (x1,y1,x2,y2)?
Do they represent the top-left and bottom-right corners of the square?
Also, can you guarantee there's only rotation between the squares or do you need a full affine transformation which allows for scaling, skewing, and translation?
Or do you also need a perspective transformation?
Only if it's a perspective transformation, will you need 3x3 matrix with 8 dof as you've mentioned in your post.