How can I find out the index of the points here?
8 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Ashfaq Ahmed
le 17 Fév 2023
Commenté : Ashfaq Ahmed
le 21 Fév 2023
HI! I have this interesting indexing question.
I have a cloud data set (attached, Cloud.mat). Plotting the X and Y, I get this figure. My question is - I want to find all the indices that falls under these four sections. Can any one please tell me how can I get the indices? Any feedback will be much appreciated.
0 commentaires
Réponse acceptée
John D'Errico
le 17 Fév 2023
Modifié(e) : John D'Errico
le 18 Fév 2023
Pretty easy. (Easier yet, IF the lines were drawn at right angles. If they were, then we could do it in literally one line of code.) But I can see they are NOT exactly perpendicular to each other, so this will take a couple more lines of code, but not many.
Anyway, just create a simple triangulation.
triXY = [-1.5 -1.5;1.5 -1.5;-1.5 2;1.5 2;0 0.25]
triangles = [1 2 5;1 3 5;2 4 5;3 4 5];
T = triangulation(triangles,triXY)
xy = rand(10,2)*3 - 1.5; % some random points.
trimesh(triangles,triXY(:,1),triXY(:,2))
hold on
plot(xy(:,1),xy(:,2),'ro')
axis equal
Next, we consider what tools a triangulation can use.
methods(T)
In there, we see that pointLocation is a method for this class. That may help me.
help pointLocation
pointLocation(T,xy)
The index returned indicates where the corresponding point fell. You can skip the plots, as you wish.
A second solution is also not difficult. This relies on an affine transformation, if the points in the plane. Think of the data as a coordinate system around an origin at the point (0,0.25). Thus, where the lines cross. A problem is, the lines have the wrong slopes, as they are not perpendicular to each other. We can resolve that simply enough, by scaling y by a factor of 3/3.5. And then we can rotate the coordinate system by 45 degrees.
The final transformation, if we have an array xy of size nx2:
ang = -45; %degree rotation, so a clockwise rotation of 45 degrees
T = @(xy) (xy - [0 0.25]).*[1 3/3.5]*[cosd(ang) sind(ang);-sind(ang) cosd(ang)];
THe function handle T uses capabilities introduced in R2016b. Earlier releases would use bsxfun.
If you look at the transformation, first notice I subtract off 0.25 from y only, so x is unchanged. Effecively, now the lines cross at the origin.
Next, I scaled the problem, so multiplying y by a factor of 3/3.5. That effectively corrects the two lines so they are now perpendicular after the rotation. (This was the error @Walter Roberson made in his suggestion.)
Finally, the 2x2 matrix I multiply by there is a rotation matrix. I've used sind and cosd there so it is clear how it was formed. See what the transformation did to the points listed in triXY.
triXY
T(triXY)
The 5th point now lies at the origin. And each of the other points have been properly scaled, and then rotated. Now, how can we use the above transformation? I'll rotate the points in the array xy, into a new array, then plot the transformation.
newxy = T(xy);
figure
plot(xy(:,1),xy(:,2),'o')
hold on
trimesh(triangles,triXY(:,1),triXY(:,2))
plot(newxy(:,1),newxy(:,2),'x')
plot([xy(:,1),newxy(:,1)]',[xy(:,2),newxy(:,2)]','r-')
axis equal
hold off
grid on
As you can see, the entire system of points has been shifted, stretched just a bit, and then rotated.
How can we now use this? If the final location of a point was originally in the top triangle, then it is now in the first quadrant. In that case, both the new x and the new y are positive numbers. So now we can decide which of the original (quasi-)quadrants a point lies in, merely by testing the signs of the points after rotation.
T(xy) >= 0
So if both results are 1 there, then the point lies now in the first quadrant. If both results are zero, then the point lies in the 3rd quadrant. And then you can easily distinguish the other quadrants too. A nice trick is to use a binary to decimal encoding.
(T(xy)>0)*[1;2]
As you can see, that yields an integer, so 0,1,2,3, depending on which of the original regions a point fell in. I'll let you decode which of the regions was which.
2 commentaires
Plus de réponses (2)
Torsten
le 17 Fév 2023
Modifié(e) : Torsten
le 17 Fév 2023
X = [0,10,0,-10,0,5,0,-5]
Y = [10,0,-10,0,5,0,-5,0]
syms x y
g1 = (y-2)/(x-1.5) == (-1.5-2)/(-1.5-1.5);
g2 = (y-2)/(x-(-1.5)) == (-1.5-2)/(1.5-(-1.5));
g1 = matlabFunction(solve(g1,y))
g2 = matlabFunction(solve(g2,y))
section1 = find(Y >= g1(X) & Y >= g2(X))
section2 = find(Y < g1(X) & Y > g2(X))
section3 = find(Y <= g1(X) & Y <= g2(X))
section4 = find(Y > g1(X) & Y < g2(X))
0 commentaires
Walter Roberson
le 17 Fév 2023
Subtract the center of mass. Rotate the result by +45 degrees. Now the combinations of sign() of the transformed x and y coordinates tells you which sector you started from.
1 commentaire
John D'Errico
le 18 Fév 2023
Modifié(e) : John D'Errico
le 18 Fév 2023
Except that the lines drawn are not perpendicular to each other. It would be nice if they were, but they are not.
Check the slopes of the lines. One of them has a slope of
3.5/3
The other slope is
-3.5/3
If they were perpendicular, the slopes would be the negative reciprocal of each other.
You could still perform an appropriate transformation that would make the idea work. But not just a 45 degree rotation.
Voir également
Catégories
En savoir plus sur Resizing and Reshaping Matrices dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!