What (if any) is the relationship between vectors used in programming languages (e.g. arrays) and vector graphics?
Why do they share the term vector? Does it represent some analogous aspect of their nature or is it coincidence?
When thinking about it, a bitmap image would fit the term vector graphic better since it's represented by an array of pixels..
a vector is a set of values, which "normally" (mathematicians would kill me) represent the coefficients of a linear combination of things (functions, or other vectors).
For example, when you say
[4, 3, 7]
and your basis is the set of power exponents of x (i.e. 1, x, x^2, x^3 etc...), this vector expresses the polynom
4 + 3x + 7 x^2
if you use a different basis, for example arbitrary directions in 3d space, that same vector expresses a direction in 3d space.
4i + 3j + 7k
(lateral consideration: please note that 3d space is a finite vectorial space of dimension 3, while the polynomial space is an infinite vectorial space, or a Hilbert space as it is better defined)
This is a vector (think an arrow) pointing in a specific direction in space, from an origin to an end. The convention is that i,j, and k are the so called basis set vectors of the 3d vectorial space, where the coordinates of each point are expressed as x,y and z. In other words, every point in space, and every direction in space, can be expressed with a triple of numbers (a vector) x, y, z which represents the spatial vector x * i + y * j + z * k.
In vector graphics, you express graphical entities not as a grid of pixel (raster graphics) but as mathematical formulas. A curve is described as a parametrized mathematical expression. This opens up a lot of nice properties for displaying, because a mathematical description has basically infinite resolution. You can also apply mathematical transformation on these entities, like rotation, without ruining its description, and these transformations are deeply rooted in linear algebra, the discipline governing transformation of vectorial spaces, matrices and so on...
They share a root meaning in mathematics.
The graphics meaning (a continuously valued offset from on arbitrary position in space), derives from the fact that you use mathematical vectors to represent it (e.g. one to represent the starting point and to represent the offset).
The programming language meaning (an ordered set of numbers) is one way of writing down the mathematical version.
A vector is an ordered group of values, such as <1, 2, 3>. It is different to an array because it is a fixed size and represents a number of values and their position in the vector is significant. An array is just an ordered collection of things. The order of elements matters but not their position. The things in it are generally all of the same type.
If the vector represented <# apples, # oranges, # pears> then it could be interpreted as <1 apple, 2 oranges, 3 pears>. If it represented <X position, Y position, Z position> then the above might mean <1 in the X axis, 2 in the Y axiz, 3 in the Z axis> (a Euclidean vector). Thus vectors can represent co-ordinates in arbitrary dimensions and are used to store information in vector graphics.
I guess it comes from the mathematical term 'vector', which is a geometrical concept. When you operate on mathematical vectors, which (in theory) have their values in continuous domains, instead of on discrete pixels, you can compute with arbitrary precision. In a graphics application, it means that you can retain precise point positions regardless of the zoom factor you are displaying your picture at.
Vector graphic is different that 'normal' graphic because it can be zoomed without aliasing. It is called vector graphic because each line or other object are represented by a vector instead of the "by pixel" normal grahic.
Related
For 2-dimensional sampled curves (an array of 2D points) there exists the Rahmer-Douglas-Peucker algorithm which only keeps "important" points. It works by calculating the perpendicular distance of each point (or sample) to a line that connects the first and the last point of. If the maximum distance is larger than a value epsilon the point is kept and the array is split into 2 parts. For both parts the operation is repeated (maximal perpendicular distance, if larger than epsilon etc.) The smaller epsilon the more detail is kept.
I am trying to write a function that can also do this for higher arrays of higher dimensional points. But I am unsure how to define distance. Or if this is actually a good idea.
I guess there exist lots of complicated and elegant algorithms that fit the curves to beziers and NURBS and what not. But are there also relatively simple ones?
I would prefer not to use beziers, but simply to identify "important" N-dimensional points.
You could extend your 2D algorithm using algebra and the L2 norm. Let's say you want to calculate the distance from a point X to a line segment PQ (where X, P and Q are defined as N-dimensional vectors).
First you can calculate the vector "proj" as:
Then, the distance is the module of the vector V = PX-proj.
For this calculation you only need the dot product between vectors, and that is well defined for N-dimensional spaces.
Using this approach I have successfuly used Rahmer-Douglas-Peucker algorithm in 3D.
E.g., when processing the set of plane contours:
each one consists of N nodes and may be described by the matrix N*2
(x, y coordinates of every node).
The number of nodes in the contour is changed during processing.
What is the simplest recommended object (data type) in Julia for such set of contours?
Simplest possible in what way? See GeometryTypes.jl. The "simplest" object, by some definitions of simple, is a vector of 3D points, with (x, y) the node coordinates and z the contour height value. You could use Point3f0 with Float32 or Point3d{T} for Int or Float64. Here you could index with ranges, as Matt suggested above.
If there is a desire for "simple" here to mean keep the contour value in a different category altogether than the (x, y) points, perhaps to save memory, then a Dict{Float32, Vector{Point2f0}}() would do that. The Dict keys would represent the contour numbers. This allows quick indexing by contour but terrible indexing by X and Y ranges as a price for the better memory usage.
If the contour indexes are so regular and predefined that storing them with the points does not matter, you could use Vector{Vector{Point2f0}}, a vector of vectors of Point2f0, with one vector of Point2f0 per contour in your vector of vectors.
I'm trying to calculate the zoom percentage from a projection matrix. The following code works as long as the image isn't rotated:
void UpdateZoomPercent()
{
var zoom = _projMatrix.M11 * glControl.Width / 2; // M11 is the top left value
lblZoomPercent.Text = (zoom * 100).ToString("G3") + "%";
}
Essentially it just takes the X scale and then multiplies it out to the viewport. X an Y will always be scaled proportionally, so I don't need to look at Y. My scene is 2D.
How do I factor in rotation?
Consider a matrix of real values forming base of a cartesian coordinate system. Each column represents a base vector. In the case of a isometric zoom, all base vectors have the same length. Let C(M,n) denote the n-th column vector of matrix M, i.e. C(M,n) = M_n,j, then for a isometric zoom it would be len(C(M,0)) = len(C(M,1)) = len(C(M,…)), where len(v) = sqrt(v·v)
In the case of anisometric scaling the length of the base vectors would differ, which is what you can use to detect this situation.
In computer graphics the matrices you encounter are homogenous to allow for a single matrix to represent all possible transformations within the space they represent. Homogenous matrices have N+1 rows and columns, where N is the number of dimensions of the coordinate space represented by them. By convention (at least in all popular computer graphics software) the upper left part (i.e. M_i,j where i and j in 1…N, 1-based index) form the base vectors, while the Nth column and row form the homogenous part.
So in case of OpenGL you'd look at the upper left 3×3 submatrix as coordinate base vectors. And since OpenGL indexes column major order you don't have to reorder what's retrieved from OpenGL.
I have a set of points (with unknow coordinates) and the distance matrix. I need to find the coordinates of these points in order to plot them and show the solution of my algorithm.
I can set one of these points in the coordinate (0,0) to simpify, and find the others. Can anyone tell me if it's possible to find the coordinates of the other points, and if yes, how?
Thanks in advance!
EDIT
Forgot to say that I need the coordinates on x-y only
The answers based on angles are cumbersome to implement and can't be easily generalized to data in higher dimensions. A better approach is that mentioned in my and WimC's answers here: given the distance matrix D(i, j), define
M(i, j) = 0.5*(D(1, j)^2 + D(i, 1)^2 - D(i, j)^2)
which should be a positive semi-definite matrix with rank equal to the minimal Euclidean dimension k in which the points can be embedded. The coordinates of the points can then be obtained from the k eigenvectors v(i) of M corresponding to non-zero eigenvalues q(i): place the vectors sqrt(q(i))*v(i) as columns in an n x k matrix X; then each row of X is a point. In other words, sqrt(q(i))*v(i) gives the ith component of all of the points.
The eigenvalues and eigenvectors of a matrix can be obtained easily in most programming languages (e.g., using GSL in C/C++, using the built-in function eig in Matlab, using Numpy in Python, etc.)
Note that this particular method always places the first point at the origin, but any rotation, reflection, or translation of the points will also satisfy the original distance matrix.
Step 1, arbitrarily assign one point P1 as (0,0).
Step 2, arbitrarily assign one point P2 along the positive x axis. (0, Dp1p2)
Step 3, find a point P3 such that
Dp1p2 ~= Dp1p3+Dp2p3
Dp1p3 ~= Dp1p2+Dp2p3
Dp2p3 ~= Dp1p3+Dp1p2
and set that point in the "positive" y domain (if it meets any of these criteria, the point should be placed on the P1P2 axis).
Use the cosine law to determine the distance:
cos (A) = (Dp1p2^2 + Dp1p3^2 - Dp2p3^2)/(2*Dp1p2* Dp1p3)
P3 = (Dp1p3 * cos (A), Dp1p3 * sin(A))
You have now successfully built an orthonormal space and placed three points in that space.
Step 4: To determine all the other points, repeat step 3, to give you a tentative y coordinate.
(Xn, Yn).
Compare the distance {(Xn, Yn), (X3, Y3)} to Dp3pn in your matrix. If it is identical, you have successfully identified the coordinate for point n. Otherwise, the point n is at (Xn, -Yn).
Note there is an alternative to step 4, but it is too much math for a Saturday afternoon
If for points p, q, and r you have pq, qr, and rp in your matrix, you have a triangle.
Wherever you have a triangle in your matrix you can compute one of two solutions for that triangle (independent of a euclidean transform of the triangle on the plane). That is, for each triangle you compute, it's mirror image is also a triangle that satisfies the distance constraints on p, q, and r. The fact that there are two solutions even for a triangle leads to the chirality problem: You have to choose the chirality (orientation) of each triangle, and not all choices may lead to a feasible solution to the problem.
Nevertheless, I have some suggestions. If the number entries is small, consider using simulated annealing. You could incorporate chirality into the annealing step. This will be slow for large systems, and it may not converge to a perfect solution, but for some problems it's the best you and do.
The second suggestion will not give you a perfect solution, but it will distribute the error: the method of least squares. In your case the objective function will be the error between the distances in your matrix, and actual distances between your points.
This is a math problem. To derive coordinate matrix X only given by its distance matrix.
However there is an efficient solution to this -- Multidimensional Scaling, that do some linear algebra. Simply put, it requires a pairwise Euclidean distance matrix D, and the output is the estimated coordinate Y (perhaps rotated), which is a proximation to X. For programming reason, just use SciKit.manifold.MDS in Python.
The "eigenvector" method given by the favourite replies above is very general and automatically outputs a set of coordinates as the OP requested, however I noticed that that algorithm does not even ask for a desired orientation (rotation angle) for the frame of the output points, the algorithm chooses that orientation all by itself!
People who use it might want to know at what angle the frame will be tipped before hand so I found an equation which gives the answer for the case of up to three input points, however I have not had time to generalize it to n-points and hope someone will do that and add it to this discussion. Here are the three angles the output sides will form with the x-axis as a function of the input side lengths:
angle side a = arcsin(sqrt(((c+b+a)*(c+b-a)*(c-b+a)*(-c+b+a)*(c^2-b^2)^2)/(a^4*((c^2+b^2-a^2)^2+(c^2-b^2)^2))))*180/Pi/2
angle side b = arcsin(sqrt(((c+b+a)*(c+b-a)*(c-b+a)*(-c+b+a)*(c^2+b^2-a^2)^2)/(4*b^4*((c^2+b^2-a^2)^2+(c^2-b^2)^2))))*180/Pi/2
angle side c = arcsin(sqrt(((c+b+a)*(c+b-a)*(c-b+a)*(-c+b+a)*(c^2+b^2-a^2)^2)/(4*c^4*((c^2+b^2-a^2)^2+(c^2-b^2)^2))))*180/Pi/2
Those equations also lead directly to a solution to the OP's problem of finding the coordinates for each point because: the side lengths are already given from the OP as the input, and my equations give the slope of each side versus the x-axis of the solution, thus revealing the vector for each side of the polygon answer, and summing those sides through vector addition up to a desired vertex will produce the coordinate of that vertex. So if anyone can extend my angle equations to handling beyond three input lengths (but I note: that might be impossible?), it might be a very fast way to the general solution of the OP's question, since slow parts of the algorithms that people gave above like "least square fitting" or "matrix equation solving" might be avoidable.
Problem: Suppose you have a collection of points in the 2D plane. I want to know if this set of points sits on a regular grid (if they are a subset of a 2D lattice). I would like some ideas on how to do this.
For now, let's say I'm only interested in whether these points form an axis-aligned rectangular grid (that the underlying lattice is rectangular, aligned with the x and y axes), and that it is a complete rectangle (the subset of the lattice has a rectangular boundary with no holes). Any solutions must be quite efficient (better than O(N^2)), since N can be hundreds of thousands or millions.
Context: I wrote a 2D vector field plot generator which works for an arbitrarily sampled vector field. In the case that the sampling is on a regular grid, there are simpler/more efficient interpolation schemes for generating the plot, and I would like to know when I can use this special case. The special case is sufficiently better that it merits doing. The program is written in C.
This might be dumb but if your points were to lie on a regular grid, then wouldn't peaks in the Fourier transform of the coordinates all be exact multiples of the grid resolution? You could do a separate Fourier transform the X and Y coordinates. If theres no holes on grid then the FT would be a delta function I think. FFT is O(nlog(n)).
p.s. I would have left this as a comment but my rep is too low..
Not quite sure if this is what you are after but for a collection of 2d points on a plane you can always fit them on a rectangular grid (down to the precision of your points anyway), the problem may be the grid they fit to may be too sparsly populated by the points to provide any benefit to your algorithm.
to find a rectangular grid that fits a set of points you essentially need to find the GCD of all the x coordinates and the GCD of all the y coordinates with the origin at xmin,ymin this should be O( n (log n)^2) I think.
How you decide if this grid is then too sparse is not clear however
If the points all come only from intersections on the grid then the hough transform of your set of points might help you. If you find that two mutually perpendicular sets of lines occur most often (meaning you find peaks at four values of theta all 90 degrees apart) and you find repeating peaks in gamma space then you have a grid. Otherwise not.
Here's a solution that works in O(ND log N), where N is the number of points and D is the number of dimensions (2 in your case).
Allocate D arrays with space for N numbers: X, Y, Z, etc. (Time: O(ND))
Iterate through your point list and add the x-coordinate to list X, the y-coordinate to list Y, etc. (Time: O(ND))
Sort each of the new lists. (Time: O(ND log N))
Count the number of unique values in each list and make sure the difference between successive unique values is the same across the whole list. (Time: O(ND))
If
the unique values in each dimension are equally spaced, and
if the product of the number of unique values of each coordinate is equal to the number of original points (length(uniq(X))*length(uniq(Y))* ... == N,
then the points are in a regular rectangular grid.
Let's say a grid is defined by an orientation Or (within 0 and 90 deg) and a resolution Res. You could compute a cost function that evaluate if a grid (Or, Res) sticks to your points. For example, you could compute the average distance of each point to its closest point of the grid.
Your problem is then to find the (Or, Res) pair that minimize the cost function. In order to narrow the search space and improve the , some a heuristic to test "good" candidate grids could be used.
This approach is the same as the one used in the Hough transform proposed by jilles. The (Or, Res) space is comparable to the Hough's gamma space.