6 votos

Cómo marcar los puntos racionales en una esfera

He encontrado esta imagen en mathoverflow, que me parece muy interesante y me gustaría saber cómo dibujar una imagen con un simple programa de ordenador.

Para calcular el punto racional, puede dibujar una línea desde P_0(0,0,1) y P_1(u,v,0) y calcular la intersección con la esfera de la siguiente manera:

\begin{equation} x=\frac{2u}{u^2+v^2+1};y=\frac{2v}{u^2+v^2+1};z=\frac{u^2+v^2-1}{u^2+v^2+1} \end{equation}

Para la intersección de las coordenadas son números racionales donde

\begin{equation} a=2u;b=2v;c=u^2+v^2-1;d=u^2+v^2+1 \end{equation}

con

\begin{equation} a^2+b^2+c^2=d^2 \end{equation}

Si entiendo correctamente el tipo que ha publicado la imagen que él iba a marcar los puntos en función del valor de d. De modo que un valor de d por debajo de un cierto umbral podría reemplazar el color de los píxeles de color blanco.

Ahora dentro de un programa que sería el bucle a través de todos los píxeles a lo largo de los ejes x y y usando el siguiente algoritmo:

for(int y = 0; y < height; ++y)
{
    for(int x = 0; x < width; ++x)
    {
        // does pixel ray intersect with sphere?
        // using orthgraphic projection ( all rays are parallel ) of 
        // sphere with radius of image height
        if(intersect(sphere,x,y))
        {
            // calculate the distance of the intersection of 
            // pixel ray and sphere
            double z = calc_distance(sphere,x,y);

            // the further away the darker the color
            rgb_color color = make_color(z);

            // calculate d
            // the gcd of a,b,c,d will be used to make d as small as possible
            int d = calculate_denominator(x,y)

            // 100 is made up
            if(d < 100)
            {
                color = white;
            }

            set_pixel(img,x,y,color);
        }
    }
}

Podría alguien ayudar en la corrección de mi algoritmo?

9voto

gagneet Puntos 4565

Me gustaría recorrer $u$ $v$ lugar, desde el punto de que, en realidad, tiene fácil racional de coordenadas no es exactamente en un píxel de la posición.

double d;
for (int u = 0; u <= 100; ++u) {
  for (int v = 0; (d = u*u+v*v+1) <= 100; ++v) {
    markBlack(2*u/d, 2*v/d); // arguments are double in [0,1]
  }
}

o, si usted desea permanecer en la aritmética de enteros:

int d;
for (int u = 0; u <= 100; ++u) {
  for (int v = 0; (d = u*u+v*v+1) <= 100; ++v) {
    int dh = d/2; // rounded down
    int x = (size*2*u + dh)/d;
    int y = (size*2*v + dh)/d;
    set_pixel(img,x,y,black);
  }
}

En ambos casos, estoy ommitting la tercera coordenada, ya que estamos proyectando sobre un plano de coordenadas.

La imagen todavía no se ve como la que se indica, sin embargo. Eso es probablemente porque usted tendría que considerar fraccional $u,v$. Usted puede ser mejor el uso de Pitágoras se cuadruplica en su lugar. A continuación, puede utilizar bucles anidados allí.

int size = 2047, limit = 100;
int dm, dn, dp, d;
for (int m = 0; (dm = m*m) <= limit; ++m)
  for (int n = 0; (dn = dm + n*n) <= limit; ++n)
    for (int p = 0; (dp = dn + p*p) <= limit; ++p)
      for (int q = 0; (d = (dp + q*q) <= limit; ++q) {
        if (d == 0) continue;
        int a = abs(m*m + n*n - p*p - q*q);
        int b =     2*(m*q + n*p) ;
        int c = abs(2*(n*q - m*p));
        int dh = d/2;
        int x = (size*a + dh)/d;
        int y = (size*b + dh)/d;
        int z = (size*c + dh)/d;
        set_pixel(img,x,y,black);
        set_pixel(img,x,z,black);
        set_pixel(img,y,x,black);
        set_pixel(img,y,z,black);
        set_pixel(img,z,x,black);
        set_pixel(img,z,y,black);
      }

Sin embargo, en lugar de marcar los píxeles de color negro o blanco, también podría considerar la posibilidad de marcar con un adecuado nivel de gris, con el valor de gris en función del número de puntos racionales dentro de un píxel dado. Si usted hace esto, entonces usted quiere asegurarse de que usted marque cada punto racional exactamente una vez. Así lo hice en el código utilizado para la animación a continuación, en la construcción de este documento.

Animation

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X