## Introduction

This article describes how to map a flat 2D image (JPG, BMP, or GIF) on a sphere by using basic algebra.

The process is very simple where the x axis of the image will be mapped on sphere longitudes and the y axis of the image will be mapped on sphere latitudes.

The process of mapping is similar to proportion equations x-x0/y-y0 = px-x0/py-y0

public static double MapCoordinate(double i1, double i2, double w1,
double w2, double p)
{
return ((p - i1) / (i2 - i1)) * (w2 - w1) + w1;
}

^{Original image}

^{Resulting image}

## Background

### A Sphere Can Be Represented by Spherical Coordinates in R^{3}

- radius
- phi (latitude angle)
- theta (longitude angle)

#### Image 2

- Where radius is a constant, phi=[-PI/2,PI/2], and theta=[0,2*PI]

### To Find the Cartesian Coordinates from Spherical Coordinates

- x = radius * sin(phi) * cos(theta)
- y = radius * sin(phi) * sin(theta)
- z = radius * cos(theta)

double phi0 = 0.0;
double phi1 = Math.PI;
double theta0 = 0.0;
double theta1 = 2.0*Math.PI;

## The Code

At first we code the image loading

System.Drawing.Image image1 = new Bitmap(Server.MapPath(
"./images/worldmap4.gif"));
Bitmap imgBitmap = new Bitmap(image1);

Now we make a loop through the 2 dimensions of the image, map phi and theta angles from image coordinates, get the cartesian 3D coordinates from phi and theta, provide some rotation to the obtained 3D points and plot them with respective image color:

for (int i = 0; i < imgBitmap.Width; i++)
{
for (int j = 0; j < imgBitmap.Height; j++)
{
double theta = Algebra.MapCoordinate(0.0, imgBitmap.Width - 1,
theta1, theta0, i);
double phi = Algebra.MapCoordinate( 0.0, imgBitmap.Height - 1,phi0,
phi1, j);
double x = radius * Math.Sin(phi) * Math.Cos(theta);
double y = radius * Math.Sin(phi) * Math.Sin(theta);
double z = radius * Math.Cos(phi);
RotX(1.5, ref y, ref z);
RotY(-2.5, ref x, ref z);
if (z > 0)
{
Color color = imgBitmap.GetPixel(i, j);
Brush brs = new SolidBrush(color);
int ix = (int)x + 100;
int iy = (int)y + 100;
graphics.FillRectangle(brs, ix, iy, 1, 1);
brs.Dispose();
}
}
}

## The Rotation Functions [almost forgot]

Actually I made a 3D Math class, but here you will need only these functions

public static void RotX(double angle, ref double y, ref double z)
{
double y1 = y * System.Math.Cos(angle) - z * System.Math.Sin(angle);
double z1 = y * System.Math.Sin(angle) + z * System.Math.Cos(angle);
y = y1;
z = z1;
}
public static void RotY(double angle, ref double x, ref double z)
{
double x1 = x * System.Math.Cos(angle) - z * System.Math.Sin(angle);
double z1 = x * System.Math.Sin(angle) + z * System.Math.Cos(angle);
x = x1;
z = z1;
}
public static void RotZ(double angle, ref double x, ref double y)
{
double x1 = x * System.Math.Cos(angle) - y * System.Math.Sin(angle);
double y1 = x * System.Math.Sin(angle) + y * System.Math.Cos(angle);
x = x1;
y = y1;
}

See sample