How can I compute the diameter of the circle that circumscribes an irregular object? - matlab

I want a function to compute and get the diameter of the circle that circumscribes the object. Is there a built-in function in MATLAB to do this? Otherwise, what can I do?

Try this algorithm:
Compute the average x and average y for every point in the irregular object. This is done by taking the x and y component for every point and add them into the total x and total y and then divide by the number of points. This average x and average y point algorithm gives you a non-weighted center of the object.
Use that center point to compute the distance for every point in the irregular object again. Keeping the largest distance as the radius of the object.
Use the center point and the radius to compute the circumference.
I am submitting proof that the distance between the 2 points that are furthest apart in the object fails with a simple triangle. See image below. Also, the big-O notation for computing the two points that are the furthest apart is x^2. The big-O for this algorithm is 2x. The diameter of the circle in the image would be computed as 20; distance between -10,0 and 10,0. A circle of diameter 20 will not encompass the point # 0,-11. Any movement of the circle would automatically remove at least one of the two points used to compute the diameter of the circle because both points are on tangents.

Suppose M is a mask in BW, just do :
[b_x,b_y] = find(bwperim(M)== 1)
Check this function bwperim

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.

helix central axis angle

I have N points in [x,y,z] and this kind of takes a helix shape. Is it possible to find the central axis of such a helix. This is not a regular helix with the central axis as either of global X, Y and Z axis
When I plot the curve looks at a particular angle to the global Z axis.
My aim is to know the angle the central axis is making with the global z axis?
If your N points are dense enough (or equi-distant), the tangential vectors (diff vectors of consecutive points) will form a cone whose direction of the center axis coincides with direction of the helix axis and whose base plane is orthogonal to this axis direction. A projection of the helix into this normal plane will give a circle with a center on the helix axis.
I do not use Matlab as I got aversion to it but based on your plot I would approach this problem like this:
take first 1-2 screws and compute its BBOX
the center point of this BBOX call A
take last 1-2 screws and compute its BBOX
the center point of this BBOX call B
compute helix estimate
So line AB should be very near to your helix axis. Now just find avg or max perpendicular distance to it that is your radius. Use these as initial values for fitting and search around them to minimize error.
Perpendicular distance of any point P to AB can be computed with vector math like this:
U = B-A
V = P-A
W = (U.V)/|U|
D = V-W
dist = |D|
where (U.V) is dot product and |U| is vector length.
fit cylinder/helix more precisely
so just search around initial guess/estimate to minimize avg and or max distance of points and fitted cylinder/helix surface. For more info and examples see:
How approximation search works
[Notes]
If you do not know how to select screws then divide your set to halves and use one for A and second for B ...
if the point density is constant you can compute curve length (sum the lines), count of screws(bumps in any axis) , height of helix (distance between first and last point) and from that infer radius as curve_length = ~sqrt((2*pi*r*screw)^2 + AB_distance^2)
I will assume that:
that the points on the helix are in the array pos with first dimension for time (or step) and second one for the 3 components of the position vector;
the time variable is stored in the array time.
You can calculate the tangent vectors:
Tangent=diff(pos(:,1:3))./(diff(time));
Then take the mean of this:
meanTangent=mean(Tangent);
and you have your axis.

Find points in an area

Given 4 points of an area, I want to calculate 30 random points inside the area. Is there a way to do that fast? I ask this because if there is a library to do that I could calculate more than 30 random points.
Do you mean 4 corners? Find the transform that maps your shape to a square, calculate random uniform coordinates in the square, then map back to your shape with the inverse transform.

Creating a mask with 3 point in Matlab?

I have this 3 points (x,y) and I need to obtain a mask with a triangle where vertices is the points. I should respect some parameters, like the pixel pitch and I need a grid from the minimum x cordinate to the maximum x coordinate (the same for the y).
I tried to do this in matlab with the function poly2mask but the problem is the resultant image: when I have negative coordinates, I cannot see the polygon.
So I tried to center the polygon but I loose the original coordinates and I cannot have they back again because I need to do some elaboration on the image.
How I can obtain a mask triangle from 3 points without modifying the points and respecting the parameters?

Dividing a geographic region

I have a certain geographic region defined by the bottom left and top right coordinates. How can I divide this region into areas of 20x20km. I mean in practial the shape of the earth is not flat it's round. The bounding box is just an approximation. It's not even rectangular in actual sense. It's just an assumption. Lets say the bottomleft coordinate is given by x1,y1 and the topright coordinate is given by x2,y2, the length of x1 to x2 at y1 is different than that of the length between x1 to x2 at y2. How can I overcome this issue
Actually, I have to create a spatial meshgrid for this region using matlab's meshgrid function. So that the grids are of area 20x20km.
meshgrid(x1:deltaY:x2,y1:deltaX:y2)
As you can see I can have only one deltaX and one deltaY. I want to choose deltaX and deltaY such that the increments create grid of size 20x20km. However this deltaX and deltaY are supposed to vary based upon the location. Any suggestions?
I mean lets say deltaX=del1. Then distance between points (x1,y1) to (x1,y1+del1) is 20km. BUt when I measure the distance between points (x2,y1) to (x2, y1_del1) the distance is < 20km. The meshgrid function above does creates mesh. But the distances are not consistent. Any ideas how to overcome this issue?
Bear in mind that 20km on the surface of the earth is a REALLY short distance, about .01 radians - so the area you're looking at would be approximated as flat for anything non-scientific. Assuming it is scientific...
To get something other than monotonic steps in meshgrid you should create a function which takes as its input your desired (x,y) and maps it relative to (x_0,y_0) and (x_max,y_max) in your units of choice. Here's an inline function demonstrating the idea of using a function for meshgrid steps
step=inline('log10(x)');
[x,y]=meshgrid(step(1:10),step(1:10));
image(255*x.*y)
colormap(gray(255))
So how do you determine what the function should be? That's hard for us to answer exactly without a little more information about what your data set looks like, how you're interacting with it, and what your accuracy requirements are. If you have access to the actual location at every point, you should vary one dimension at a time (if your data grid is aligned with your latitude grid, for example) and use a curve fit with model selection techniques (akaike/bayes criterion) to find the best function for your data.