How to draw a best fit mesh on a set of points in 2D - matlab

I have a problem where we have a grid of points and I'd like to fit a "deformed grid which would best fit the set of points.
The MatLab data can be found at:
https://drive.google.com/file/d/14fKKEC5BKGDOjzWupWFSmythqUrRXae4/view?usp=sharing
You will see that cenX and cenY are the x and y coordinates of these centroids.
Like on this image. To note is that there are points missing, and there are a few extra points. Moreover, You can see some lines are not one single line from left to right, however, we could safely assume that the fitting a line somewhat horizontally (+-5degrees) would properly link the points into a somewhat deformed grid.
The vertical lines are trivial because that is how we generated these dots. We can find the number of lines required through a mode of the count of points on each of the columns of the grid.
I'd like to be able to ensure that a point is only part of one line, as this is a grid.

Related

Placing labels evenly along curved 3D mesh

I have a single mesh game object that is essentially a long line that curves and slopes up/down. What I'm trying to do is generate some text along this line at a specified distance interval. Let's say every 100 units along the line some text should appear. If it was a straight line it would be easy, but the curves and slopes are throwing me off.
I retrieved the vertices that created this mesh by doing:
model.GetComponent<MeshFilter>().mesh.vertices
I then transform them to world-space by looping over them and doing:
meshFilter.gameObject.transform.TransformPoint(vertices[i])
Now, these vertices are NOT evenly spaced. For slopes and curves, there are a lot of vertices. For the straighter parts, there are less. But these straight parts still vary slightly (usually by ~.10 of the Y value). Originally I was looping through and keeping track of the distance to find the vertices closest to the interval, but that was when I thought they were evenly spaced.
Here's part of the model:
I colored all the vertices black here to show how condensed they are at curves/slopes vs ~straight parts:
Here's the inspector for the model just incase:
Do you use a static single mesh?
In your solution, I think the problem is vertices. you have to find vertices along your line and ignore the vertical group of them and its too difficult.
If your mesh may be changed by player, I suggest you to use Trail Render Component, get its vertices and solve a simple Knapsack problem to put your characters (suggest you use TextmeshPro)

impoly only approximately correct on log-scale axes

When determining points within polygons using MATLAB's inpolygon function, I find that the results are exactly correct for polygons drawn on linear axes but only approximately correct for polygons drawn on log-scale axes. Although my suspicions lean in favor of a MATLAB bug, it's possible I've overlooked something.
The following code reproduces the issue I have been experiencing with other data. The results are shown in the following image (the bottom set of panels are zoomed views of the top panels). One can appreciate that there are unlabeled points inside the polygon and labeled points outside the polygon, neither of which should occur, in the case of a polygon drawn on log-scale axes (right). In contrast, the polygon test is exact for polygons drawn on linear axes (left).
n=2E4;
x(:,1)=rand(n,1); y(:,1)=rand(n,1);
x(:,2)=lognrnd(0.5,0.25,n,1); y(:,2)=lognrnd(0.5,0.25,n,1);
for m=1:2
subplot(1,2,m);
scatter(x(:,m),y(:,m),'.'); hold on;
if(m==2)
set(gca,'xscale','log'); set(gca,'yscale','log');
end
p=impoly(gca);
pc=getPosition(p);
in=inpolygon(x(:,m),y(:,m),pc(:,1),pc(:,2));
scatter(x(in,m),y(in,m),20);
end
I think you missed something: A line in normal scale is not a line in log scale. Your polygons are not properly drawn in the log scale, as you draw 2 points and put them together with a straight line.
Look at the real polygon in log space:
close all
clear
n=2e4;
x(:,1)=rand(n,1); y(:,1)=rand(n,1);
x(:,2)=lognrnd(0.5,0.25,n,1); y(:,2)=lognrnd(0.5,0.25,n,1);
for m=1:2
subplot(1,2,m);
scatter(x(:,m),y(:,m),'.'); hold on;
if(m==2)
set(gca,'xscale','log'); set(gca,'yscale','log');
end
p=impoly(gca);
pc=getPosition(p);
% plot polygon
hold on
for ii=1:size(pc,1)-1
plot(linspace(pc(ii,1),pc(ii+1,1),100),linspace(pc(ii,2),pc(ii+1,2),100),'g')
end
plot(linspace(pc(end,1),pc(1,1),100),linspace(pc(end,2),pc(1,2),100),'g')
in=inpolygon(x(:,m),y(:,m),pc(:,1),pc(:,2));
scatter(x(in,m),y(in,m),20);
end
Look at this zoomed in result (click to enlarge):
This happens because the polygon is defined in euclidean space, and it is defined as points linked by lines. If you want to work in log space, things may get complicated. One way to numerically approximate it is the inverse of what I did for plotting. Create dense enough sampled straight line on log space, convert it to linear space, and define a high vertex polygon with the resulting points. Then use inpolygon.

Image segmentation (OCT)

My image is something like below:
I want to be able to draw 2 layers: (1) red line on top of 1st layer, but (2) blue line in the middle of 2nd layer
I am using OpenCV. but any languages/advice are welcomed.
You can do the following:
Small closing in order to reconnect the small separated components/patterns.
Small opening in order to remove the small isolated components/patterns.
Skeletonize (or median axis)
Pruning in order to remove the small branches.
You will then get a skeleton for each pattern. It will be close to the lines you want to draw. But it will be a little bit irregular, so you can interpolate it.
[EDIT] if you need the red line on top of the edge, a solution is to:
Extract the pattern contour
Keep only the pixel on top.
Algorithmically, it can be achieved doing this: for each X coordinate on the top border, go down the image vertically until you meet the first non-null pixel. If your image is NxM, you must have N pixels in your solution.
If you want to regularize/smooth the result, you have two solutions:
Transform the contour as a parametric function and smooth it.
Do an interpolation (spline?)

Fit several connected lines to points

I have an 2d-image and I want to fit several lines to the object that is represented by this image. The lines are connected and can only have angles in certain intervals between each other.
I know, that you can fit one line to data points using least squares. But I do not know how to fit several connected lines simultaneously to points while at the same time obeying the angle intervals.
How would you solve this problem programmatically? I would also accept an answer, given me catchwords (and maybe links) that will point me to my solution.
Here is an example image. For instance, I might want to fit 4 lines with length x,y,z,w to the object represented by the largest component in the image. Unfortunately, the object is not always as clearly visible as it is here, but this will do for now :)
Green lines approximate lines I would be looking for (sorry, they are not very straight ;) ).
You can fit a degree 1 B-spline curve to data points extracted from your image. A degree 1 B-spline curve is conceptually a composition of multiple line segments, which matches what you want. Additional angle constraints between lines can be imposed onto control points of this degree 1 B-spline curve but doing so will turn your unconstrained fitting into a constrained one, which will increase the complexity of algorithm.

Correct scaling of circular markers in scatter plot

I have a system of finite size circular particles (say r=5cm) which I need to plot in a given domain (say L=5m). Since they are many, scatter is faster than any cyclic use of rectangle.
What is unclear to me is the correct way to define the diameter/radius of the circles/marker so to scale correctly with the domain geometry which is plotted as well. (By using rectangle, the diameter of the particle can be easily defined.)
Based on this answer, it is possible to have fine control of the marker size, although the real scaling is obscure to me.
Can anyone shed some light?
The SCATTER function expects its 'S' parameter to contain the marker
area in points squared. This area corresponds to the area of a square
bounding box around the marker.
The source is the technical solution "How do I specify the size of the markers created by the SCATTER plot in units proportional to the data being plotted in MATLAB 7.6 (R2008a)?"
Check out the code in the link.
The official documentation states:
MarkerSize
Marker size. Size of the marker in points. The default value is 6.
Note that one point is 1/72 of an inch, so it's an absolute measurement unit.
If you want to tune the marker sizes according to the axis scale of your plot, do a simple unit conversion: calibrate 1 tick in one of the axes to points (you can do it by trial and error), and then normalize all your marker sizes by it (it doesn't, however, occur to me how you'd keep the marker sizes relative to the plot's zoom level in a straightforward manner).
By the way, you can specify the sizes of the markers directly as the third parameter in the scatter command. With this, you can avoid the get and set manipulations mentioned in the answer to which have linked your question.