Area of a skew quadrilateral - matlab

Does anyone have suggestions/algorithms on how to calculate the surface area of a skew quadrilateral? (I believe skew quadrilateral = a quadrilateral whose vertices are not planar)

If your quadrilateral is embedded in d dimensions, then you can calculate the height of the quadrilateral by projecting the vector passing through one of the parallel sides onto the line passing through the other two parallel sides and computing the projection's length between the two sides of the original direction, and then the area is the length of the projection vector multiplied by the length of the side you projected onto.

Related

Optimizing computation of distance to triangle using barycentric coordinates

Building on the discussions here and here. I'm trying to compute the shortest distance between a 3D line and a 3D triangle.
I'm using barycentric coordinates to determine whether or not the point is inside the triangle. So given a triangle defined by vertices UVW and a line defined by point AB, I first compute the intersection of line AB with the plane defined by UVW. Let's call this intersection P and assume I've already done the checks to verify whether or not the point actually intersects the plane at all.
I then compute barycentric coordinates (S,T) such that S is defined along the edge UV and T is defined along the edge UW. Naturally, if 0≤S and 0≤T and S+T≤1 then P is on the triangle (or its edge) and my distance to the triangle is obviously zero.
If that's not true then P is outside the triangle and I need to compute the distance. The guidance of from the first link says to project point P onto all three edges to get three candidate points. Adding those points to the three triangle's vertices, you then have six points to test against.
Isn't it easier than that, though? If T<0, then don't you already know that UV is the closest edge and you only have to test against the projection of P onto that line? Similarly, if S<0 then UW would be the closest edge. If T>0 and S>0 then VW is the closest edge.
Thus based on the signs of S and T you already know the closest edge and only have to compute the distance from P to its projection onto that edge. If the projection isn't inside the triangle, then the closest point is either vertex. Thus your computations are about 1/3 of the proposed methods.
Am I missing something here, or is this a valid optimization? I'm fairly new to barycentric coordinates and their attributes.
It turns out that the problem of closest distance from a point and from a line are very similar and can both be reduced to a pure 2D problem.
Distance from a point
By Pythagoras, the squared distance from a point to a point of the triangle is the sum of the squared distance to the plane of support of the triangle and the squared distance of the projection of the point to that plane.
The latter distance is precisely the distance from the normal line to the triangle.
Distance from a line
Looking in the direction of the line, you see the projected triangle and the line is reduced to a single point. The requested 3D distance is equal to the 2D distance seen on the projection.
To obtain the desired coordinates, you use an auxiliary coordinate frame such that Z is in the direction of the line (and XY is a perpendicular plane); for convenience, choose the origin of the new frame to be on the line. Then by just ignoring Z, you get a planar problem in XY. The change of coordinates is an affine tranformation.
Point vs. triangle
Consider the three triangles formed by the origin (projection of the point/line) and a pair of triangle vertices (taken in cyclic order). The signed area of these triangles is a mere 2x2 determinant.
If the three areas have the same sign, the point is inside. Otherwise, the signs tell you where you are among the six surrounding regions, either past an edge or past a vertex.
On the upper figure, the point is inside (three positive areas). On the other figure, it is outside of the top-right edge (one negative area). Also note that dividing an area by the length of the corresponding side, you get the distance to the side. (Factor 2 omitted.)
The total work is
compute the affine frame;
convert the coordinates of the 3 or 4 points;
compute the three signed areas;
if inside, you are done;
otherwise, if in an edge region, compute a distance to a line and two distances to points;
otherwise you are in a vertex region, compute two distances to lines and one distance to vertex.

Calculate angle of matrix with topography for each triangle

I have a matrix with data of a topography, let's say several hills. I want to have information of the angle of each data point to the vertical line. Here are two examples:
If I consider a place near the foot of the hill that is totally flat, I have a degree of 90° (90° to the vertical line).
If I am at the steepest point of the hill, I have a lower angle of let's say 50°.
To compute this I guess I have to to connect all the topography data so that (at least) three near pixels form triangle. After that I have to compute the angle(s) of this triangle.
Can I use a existing algorithm?
If your heightmap is a matrix A then you could approximate the the gradient components of every inner point (without the egdes) by
Xgrad = (A(2:end-1,3:end)-A(2:end-1,1:end-2))/2;
Ygrad = (A(3:end,2:end-1)-A(1:end-2,2:end-1))/2;
The angulars will then be
deg = (pi/2 - atan(sqrt(Xgrad.^2 + Ygrad.^2),1))/pi*180;
Depending on your heightmap, differentiating numerically can produce "fuzzy" results. Maybe you have to do some blur-filtering in order to produce smoother gradients.

Compute multiple faces connected at vertices from normal vectors

I have a set of 8 normal vectors in 3D space. I need to plot a cuboid with lateral wings from these vectors:
whereas vectors 4 to 6 are just the negatives (opposite sides) of the first three and the last two vectors are identical to the first one and make up the wings.
The goal is to plot this object with each surface having a different color so that I can count the pixels of each color afterward for different sets of normal vectors (i.e. determining the visibility of partially obstructed surfaces).
I have found the patch function which can plot polygons with individual colors and takes the coordinates of the vertices for input. However, I do know the dimension of each surface, but the coordinates of the vertices need to be somehow calculated for each set of normals vectors. Any suggestions on how to approach this task?
EDIT
I may have found a solution: I just noticed that view allows defined azimuth and elevation angles and thus "rotation" of the object. With the compution of azimuth and elevation from the normal vectors, the calculation of the vertices becomes unnecessary.

What exactly is edge density?

I'm kinda confuse of the meaning of edge density. From the equation,
edge density = sum(x=1,w) sum(y=1,h) e(x,y)/N
where e is the edge map image (magnitude of vertical edge at (x,y)), there are two version of N.
1st version - N = w x h (width x height)
2nd version - N = number of non zero vertical edge pixel
What I don't understand is how can I calculate the edge density? Is it just summation of the white edges pixels?
Edited
Hi all, from what I understand from reading the paper given by #Gilgamesh, the N is the area of the region, width times its height but from the answer given it seems there is a conflict whereby N refers to number of non white pixels(black pixel). So, which is the correct one? Here is another reference on the N value calculating edge density.
basically the edge density is really just a (local) average density, which you can either calculate over binarized images or, more common, over grey scale images.
And yes, it is basically just summing up over both x and y coordinates in a subimage in most cases, see equation (1) here
http://ro.uow.edu.au/cgi/viewcontent.cgi?article=1517&context=infopapers
and averaging afterwards.
Regards,
G.
From what I understand about edge density, it is defined as where are the white pixels and is the total number of pixels i.e. .
cannot be the number of black pixels because the number could be arbitrary, ranging from zero to all pixels and the range of edge density will then be .
When is the area, the range will be which portrays just what we want, the places where edges are dense (or sparse depending on your requirement).
The edge map is the map of gradient magnitude (i.e. the length of the gradient vector). So the edge density is the average of the gradient magnitude over a neighborhood.
If you have a binary edge map where 0 means no-edge, 1 means edge (this can be obtained by thresholding the gradient magnitude), then the edge density is just the ratio of edge/non-edge pixels.

Principal direction in a binary image

As shown in image, there is a binary polygonal image. I want to find the principal direction in the image with respect to X-axis. I have shown the principal direction and X-axis with blue line. This can be done using PCA but my problem is such a small rectangle will have around 1000 pixels and I have to find Principal directions for around 100 polygons (polygon can be of arbitrary shape).
One approach that I have thought is:
Project that rectangle onto a line which is oriented at degrees at an interval (say) 5 degrees. The projection which has the maximum variance is the desired projection axis, and thus that is the desired angle. But this also falls under a greedy approach and thus will take time. Is there a smarter approach?
Also, if anybody could explain the exact procedure to do this using PCA, it would be helpful. I know the steps:
1. Take the covariance matrix.
2. Get the top eigenvector corresponding to largest eigenvalue -> that will be the principal direction.
But I am confused in the following statement which I often read everywhere:
A column vector: [0.5 0.5] is the first principal component and it gives the direction of the maximum variance. So can do I exactly calculate the angle by which I should rotate the data so that it will become parallel to X-axis.
Compute the eigenvector associated with the highest eigen value. Call that v. Normalize v. v = v/norm(v);
Compute angle between that and the horizontal direction: angle=acos(sum(v.*[1,0]))
Rotate by -angle, transformation matrix T = [cos(-angle) -sin(-angle); sin(-angle) cos(-angle)], multiply all points by that matrix. Do that for all polygons.