이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
Compact way to calculate the centroid of a boundary of a set of points
조회 수: 87 (최근 30일)
이전 댓글 표시
채택된 답변
Jan
2022년 9월 30일
편집: Jan
2022년 9월 30일
The centroid of the boundary is the mean value of the coordinates:
x = rand(40, 1).^2; % More points on the left
y = rand(40, 1).^2; % More points on the bottom
k = boundary(x, y);
c = mean([x(k), y(k)], 1); % Center of points of boundary
plot(x, y, 'r.');
hold('on');
plot(x(k), y(k), 'b');
plot(c(1), c(2), '*g');
You see, that this is not the center of mass, but the centroid of points. To get the center of mass:
[CoMx, CoMy] = centroid(polyshape(x(k), y(k))); % Center of Mass
plot(CoMx, CoMy, '*k');
% or:
[cx, cy] = CenterOfMass(x(k), y(k))
function [cx, cy] = CenterOfMass(x, y)
% This fails, if lines of the polygon intersect.
x = x(:);
y = y(:);
x_ = circshift(x, 1);
y_ = circshift(y, 1);
A = x .* y_ - x_ .* y;
As = sum(A) * 3;
cx = sum((x_ + x) .* A) / As;
cy = sum((y_ + y) .* A) / As;
end
댓글 수: 16
Bruno Luong
2022년 9월 30일
"The centroid is the mean value of the coordinates"
I'm not sure if I have the same definition. I would say it is as the mass is ditributed on the boundary, so it can be calculated as the weigthed mean of the center of the segments. The weight is the length of the segment.
But as OP doesn't make any description, I'll hesitate to give that solution.
Sim
2022년 9월 30일
편집: Sim
2022년 9월 30일
Thanks both @Jan and @Bruno Luong! I was thinking at the "centroid as the mean value of the coordinates", but there might be other definitions, I do not know about other ones (@Bruno Luong?)...
About the center of mass of the points, I did not think about it.... :-)
...But then, which of the two centers would make more sense / would be more appropriate to characterize the points?
William Rose
2022년 9월 30일
@Sim,
@Jan has done a very clever thing. He creates an array of points that roughly covers the unit square, so the centroid should be near (.5,.5). The points are distributed in a parabolic way so there are more points near the origin than you'd expect for a simple 2D uniform distribution. This is smart because it creates a data set in which the mean of all the points (green *) is noticeably different from the centroid (black *).
Here is a non-random set of points that also illustrates the difference: a square plate with a skinny notch, and 7 points at the base of the notch:
x = [0 0 1 1 .03 .027 .023 .02 .023 .027 .03 1 1 ]';
y = [0 1 1 .51 .51 .508 .502 .50 .498 .492 .49 .49 0 ]';
pgon=polyshape(x,y);
c = mean([x, y], 1);
[COMx, COMy] = centroid(pgon);
plot(x, y, 'r.');
hold('on');
plot(pgon)
plot(c(1), c(2), '*g');
plot(COMx, COMy, '*k');
@Bruno Luong also has a smart question, which had not occurred to me: Is this surface a filled-in polygon, or is all its mass on the edge?
Bruno Luong
2022년 9월 30일
편집: Bruno Luong
2022년 9월 30일
My proposition is assumed a unifrorm Mass of the edge (boundary) which gives the result that is more or less invariant to the density of the sample points of the boundary.
x = [0 0 1 1 .03 .027 .023 .02 .023 .027 .03 1 1 ]';
y = [0 1 1 .51 .51 .508 .502 .50 .498 .492 .49 .49 0 ]';
pgon=polyshape(x,y);
%% Point centroid
c = mean([x, y], 1);
%% Region centroid
[COMx, COMy] = centroid(pgon);
%% Boundary centroid
xyw = [x([1:end 1])';
y([1:end 1])'];
w = sqrt(sum(diff(xyw,2).^2,1));
xym = (xyw(:,1:end-1)+xyw(:,2:end))/2;
bdrc = sum(xym.*w,2) ./ sum(w,2);
plot(x, y, 'c.');
hold('on');
plot(pgon)
h1=plot(c(1), c(2), '*g');
h2=plot(COMx, COMy, '*k');
h3=plot(bdrc(1), bdrc(2), 'or');
legend([h1,h2,h3], 'points', 'region', 'boundary')
William Rose
2022년 9월 30일
@Jan's CenterofMass() function is borderline black magic. He is a master of the dark arts of math and Matlab.
Sim
2022년 10월 1일
@William Rose Sorry, I forgot to reply to "Is this surface a filled-in polygon, or is all its mass on the edge?"
I have a bunch of points, and I create a boundary to wrap my points. Therefore, I would say that most of the mass (given by my points) lies inside the boundary and not on the boundary / edge.
:-)
Sim
2022년 10월 1일
편집: Sim
2022년 10월 1일
I have tried to make a summary of all your answers (and I got a bit confused about the meaning of the Bruno Luong's "region centroid" and "boundary centroid"):
x = rand(40, 1).^2; % More points on the left
y = rand(40, 1).^2; % More points on the bottom
k = boundary(x, y); % Get the boundary that wraps the points
pgon=polyshape(x,y);
figure('position',[100 100 600 600],'Color',[1 1 1],'Visible','on');
hold on
% Show the points
plot(x, y, 'r.');
% Show the boundary
plot(x(k), y(k), 'b');
% Center 1
% From Jan: "center of points of boundary" or "centroid of the boundary"
c = [];
c = mean([x(k), y(k)], 1);
h1 = plot(c(1),c(2),'linewidth',2,'MarkerSize',15,'Marker','.','MarkerEdgeColor','g');
% Center 2
% From Jan: "center of mass"
CoMx = []; CoMy = [];
[CoMx, CoMy] = centroid(polyshape(x(k), y(k)));
h2 = plot(CoMx, CoMy,'linewidth',2,'MarkerSize',15,'Marker','x','MarkerEdgeColor','k');
% Center 3
% From Jan: "center of mass", called "function [cx, cy] = CenterOfMass(x, y)"
x_ = []; y_ = []; A = []; As = []; cx = []; cy = [];
x = x(k);
y = y(k);
x_ = circshift(x, 1);
y_ = circshift(y, 1);
A = x .* y_ - x_ .* y;
As = sum(A) * 3;
cx = sum((x_ + x) .* A) / As;
cy = sum((y_ + y) .* A) / As;
h3 = plot(cx, cy,'linewidth',2,'MarkerSize',15,'Marker','d','MarkerEdgeColor','r');
% Center 4
% From Bruno Luong: point centroid
% From William Rose: no name
c = [];
c = mean([x, y], 1);
h4 = plot(c(1),c(2),'linewidth',2,'MarkerSize',15,'Marker','^','MarkerEdgeColor','m');
% Center 5
% From Bruno Luong: region centroid
% From William Rose: no name
COMx = []; COMy = [];
[COMx, COMy] = centroid(pgon);
h5 = plot(COMx, COMy,'linewidth',2,'MarkerSize',15,'Marker','>','MarkerEdgeColor','b');
% Center 6
% From Bruno Luong: boundary centroid
xyw = []; w = []; xym = []; bdrc = [];
xyw = [x([1:end 1])';
y([1:end 1])'];
w = sqrt(sum(diff(xyw,2).^2,1));
xym = (xyw(:,1:end-1)+xyw(:,2:end))/2;
bdrc = sum(xym.*w,2) ./ sum(w,2);
h6 = plot(bdrc(1), bdrc(2),'linewidth',2,'MarkerSize',15,'Marker','o','MarkerEdgeColor','y');
% plot(pgon)
legend([h1,h2,h3,h4,h5,h6],...
'Jan: center of points of boundary',...
'Jan: center of mass',...
'Jan: center of mass (CenterOfMass)',...
'Bruno Luong: point centroid AND William Rose: no name',...
'Bruno Luong: region centroid AND William Rose: no name',...
'Bruno Luong: boundary centroid', ...
'fontsize',15);%,'Location','northeastoutside')
hold off
set([h1,h2,h3,h4,h5,h6],'linestyle','none')
This is the result, with 4 types of centers....
From this plot we can see that:
- the Bruno Luong's "point centroid" is the Jan's "center of points of boundary" (even though the arguments of the mean are slightly different, i.e. "[x, y]" for Bruno Luong and "[x(k), y(k)]" for Jan).. right?
% From Bruno Luong: point centroid
c = mean([x, y], 1);
% From Jan: "center of points of boundary" or "centroid of the boundary"
c = mean([x(k), y(k)], 1);
- the Jan's "center of mass" is the Jan's "center of mass (with the function CenterOfMass)"
Therefore,
- I would take the Bruno Luong's "point centroid" and the Jan's "center of points of boundary" definitions as definition for the "centroid of a boundary of a set of points" as in my initial question (even though the arguments of the mean are slightly different, i.e. "[x, y]" for Bruno Luong and "[x(k), y(k)]" for Jan)
- I would also consider the Jan's definition of "center of mass".
- Still I do not understand what the Bruno Luong's "region centroid" and "boundary centroid" mean (?).
William Rose
2022년 10월 2일
@Sim,
The point centroid is the average of the locations of all the points.
The boundary centroid is the centroid of a wire of uniform density that runs along the boundary.
The region centroid is the centroid of a plate of uniform density, with the specified boundary.
If you place a lot of boundary points close together in a straight line, the point centroid will be pulled in that direction, but the boundary and region centroids won't be affected, because the wire location and the plate edge are still the same, whether it is just a few points in a line, or many.
If you add a long thin hairpin fold to the wire, the boundary centroid will be pulled in that direction, but the plate centroid will not be affected much, because the "cutout" made by the hairpin has a negligible area.
Sim
2023년 11월 23일
편집: Sim
2023년 11월 23일
% [cx, cy] = CenterOfMass(x(k), y(k))
function [cx, cy] = CenterOfMass(x, y)
% This fails, if lines of the polygon intersect.
x = x(:);
y = y(:);
x_ = circshift(x, 1);
y_ = circshift(y, 1);
A = x .* y_ - x_ .* y;
As = sum(A) * 3;
cx = sum((x_ + x) .* A) / As;
cy = sum((y_ + y) .* A) / As;
end
performs the same as in
However, it looks like you divide by 3, while, in this paper, the author divides by 6.
Did you use the same formulas or something else? Or am I missing something? I do not understand.. :-) :-) :-)
Bruno Luong
2023년 11월 23일
편집: Bruno Luong
2023년 11월 24일
@Sim The area of the polygonal (A in the book) is sum(A)/2 in Jan code.
So sum(A)*3 in Jan's code is equal to 6*area. They are the same. (EDIT typo)
추가 답변 (0개)
참고 항목
카테고리
Help Center 및 File Exchange에서 Elementary Polygons에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 MathWorks 사이트 방문이 최적화되지 않았습니다.
미주
- América Latina (Español)
- Canada (English)
- United States (English)
유럽
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
아시아 태평양
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)