Task: Draw a sphere




Go: package main

import (
    "fmt"
    "image"
    "image/color"
    "image/png"
    "math"
    "os"
)

type vector [3]float64

func normalize(v *vector) {
    invLen := 1 / math.Sqrt(dot(v, v))
    v[0] *= invLen
    v[1] *= invLen
    v[2] *= invLen
}

func dot(x, y *vector) float64 {
    return x[0]*y[0] + x[1]*y[1] + x[2]*y[2]
}

func drawSphere(r int, k, amb float64, dir *vector) *image.Gray {
    w, h := r*4, r*3
    img := image.NewGray(image.Rect(-w/2, -h/2, w/2, h/2))
    vec := new(vector)
    for x := -r; x < r; x++ {
        for y := -r; y < r; y++ {
            if z := r*r - x*x - y*y; z >= 0 {
                vec[0] = float64(x)
                vec[1] = float64(y)
                vec[2] = math.Sqrt(float64(z))
                normalize(vec)
                s := dot(dir, vec)
                if s < 0 {
                    s = 0
                }
                lum := 255 * (math.Pow(s, k) + amb) / (1 + amb)
                if lum < 0 {
                    lum = 0
                } else if lum > 255 {
                    lum = 255
                }
                img.SetGray(x, y, color.Gray{uint8(lum)})
            }
        }
    }
    return img
}

func main() {
    dir := &vector{-30, -30, 50}
    normalize(dir)
    img := drawSphere(200, 1.5, .2, dir)
    f, err := os.Create("sphere.png")
    if err != nil {
        fmt.Println(err)
        return
    }
    if err = png.Encode(f, img); err != nil {
        fmt.Println(err)
    }
    if err = f.Close(); err != nil {
        fmt.Println(err)
    }
}


Java: using System;

namespace Sphere {
    internal class Program {
        private const string Shades = ".:!*oe%&#@";
        private static readonly double[] Light = {30, 30, -50};

        private static void Normalize(double[] v) {
            double len = Math.Sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
            v[0] /= len;
            v[1] /= len;
            v[2] /= len;
        }

        private static double Dot(double[] x, double[] y) {
            double d = x[0]*y[0] + x[1]*y[1] + x[2]*y[2];
            return d < 0 ? -d : 0;
        }

        public static void DrawSphere(double r, double k, double ambient) {
            var vec = new double[3];
            for(var i = (int)Math.Floor(-r); i <= (int)Math.Ceiling(r); i++) {
                double x = i + .5;
                for(var j = (int)Math.Floor(-2*r); j <= (int)Math.Ceiling(2*r); j++) {
                    double y = j/2.0 + .5;
                    if(x*x + y*y <= r*r) {
                        vec[0] = x;
                        vec[1] = y;
                        vec[2] = Math.Sqrt(r*r - x*x - y*y);
                        Normalize(vec);
                        double b = Math.Pow(Dot(Light, vec), k) + ambient;
                        int intensity = (b <= 0)
                                            ? Shades.Length - 2
                                            : (int)Math.Max((1 - b)*(Shades.Length - 1), 0);
                        Console.Write(Shades[intensity]);
                    }
                    else
                        Console.Write(' ');
                }
                Console.WriteLine();
            }
        }

        private static void Main() {
            Normalize(Light);
            DrawSphere(6, 4, .1);
            DrawSphere(10, 2, .4);
            Console.ReadKey();
        }
    }
}