A continuación se ofrece una respuesta sencilla de fuerza bruta. Se basa en pensar en la Algoritmo del círculo del punto medio pero no lo requiere. En resumen:
-
Para el polígono interior, encuentre todos los puntos enteros que están dentro del círculo, luego tome su casco convexo.
-
Para el polígono exterior, genere un conjunto de puntos enteros que estén fuera del círculo tal que se garantice que su casco convexo también esté fuera del círculo.
Demostraré la respuesta con código MATLAB (versión R2016a, sin cajas de herramientas). En primer lugar, configure una figura con el círculo.
%% Circle
r = 2.7; % Change this to try different radii.
figure
rectangle('Position', [-r -r 2*r 2*r], 'Curvature', [1 1], ...
'LineWidth', 2, 'EdgeColor','r')
hold on
grid on
axis equal
Ahora configure una malla con puntos enteros (X,Y)(X,Y)
rIntegerRange = -ceil(r):ceil(r);
[X,Y] = meshgrid(rIntegerRange,rIntegerRange);
Polígono interior : Casco convexo de los puntos enteros adjuntos.
%% Inner Polygon - Convex hull of the enclosed integer points.
R = sqrt(X.^2 + Y.^2);
Iinside = R < r;
Xinside = X(Iinside);
Yinside = Y(Iinside);
KInnerPolygon = convhull(Xinside,Yinside);
XInnerPolygon = Xinside(KInnerPolygon);
YInnerPolygon = Yinside(KInnerPolygon);
plot(Xinside, Yinside, 'g.', 'MarkerSize', 12);
plot(XInnerPolygon, YInnerPolygon, 'g.-', 'LineWidth', 2)
Polígono exterior : Es bonito utilizar cascos convexos, pero tenemos que asegurarnos de que cuando obtenemos el casco convexo no recortamos el círculo. La solución en este caso se puede imaginar de la siguiente manera - en el primer octante, poner alfileres en el círculo donde se cruza una línea x=kx=k para los enteros kk . A continuación, empuje esas clavijas hacia arriba hasta que lleguen a una línea entera para yy . Se garantizará que el casco convexo alrededor de esos puntos quede fuera del círculo. Por último, duplica el octante en un conjunto completo de puntos alrededor del círculo.
%% Outer Polygon - Convex hull of roundups.
% First octant: Round up the y coordinate.
X1 = 0 : floor(r);
Y1 = ceil(sqrt(r^2 - X1.^2));
% Duplicate into the first quadrant ...
Xq = [X1, Y1(end:-1:1)];
Yq = [Y1, X1(end:-1:1)];
% ... and then into the full set of points.
Xoutside = [Xq, Xq, -Xq, -Xq];
Youtside = [Yq, -Yq, -Yq, Yq];
% Now obtain the convex hull.
KOuterPolygon = convhull(Xoutside,Youtside);
XOuterPolygon = Xoutside(KOuterPolygon);
YOuterPolygon = Youtside(KOuterPolygon);
plot(Xoutside, Youtside, 'b.', 'MarkerSize', 12);
plot(XOuterPolygon, YOuterPolygon, 'b.-', 'LineWidth', 2)
Observando los resultados, es evidente que el polígono exterior es conservador.
![Polygons for a circle of radius 2.7]()
Como refinamiento para eliminar puntos (que no he explorado) : Obsérvese que para tres puntos sucesivos cualesquiera (x1,y1)(x1,y1) , (x2,y2)(x2,y2) , (x3,y3)(x3,y3) en el polígono exterior, el punto medio podría ser eliminado si (tx3+(1−t)x1,ty3+(1−t)y1)(tx3+(1−t)x1,ty3+(1−t)y1) está fuera del círculo para todo 0≤t≤10≤t≤1 . Además, esto será cierto si y sólo si (tx3+(1−t)x1)2+(ty3+(1−t)y1)2≥r2(tx3+(1−t)x1)2+(ty3+(1−t)y1)2≥r2 para todos 0≤t≤10≤t≤1 . Intenta resolver la igualdad (ecuación cuadrática) y elimina el punto si no existe solución.
0 votos
Yo lo intentaría con la serie Taylor.
1 votos
Relacionado: math.stackexchange.com/questions/64897/