04
25
Office 2007 Ribbon 风格的按钮和菜单
作者:独木舟 日期:2008-04-25
[翻译]
Andalmeida著Mapping images on spherical surfaces using C#
[开发环境]
C# (C# 2.0)
Windows, .NET (.NET 2.0)
[简介]
本文描述如何使用C#映射二维图像(JPG, BMP, 或 GIF)到三维球形表面。
这个处理是非常简单的,把X轴映射成球面纬度,把Y轴映射成球面经度。
映射的过程非常象等式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;
}
原图
处理后的三维图
[背景]
一个球体能够由下面的三个球面坐标表示:
radius 半径
phi (纬度角latitude angle)
theta (经度角longitude angle)
image 2
Where radius is a constant, phi=[-PI/2,PI/2], and theta=[0,2*PI]
从球面坐标系转笛卡尔坐标系:
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;
[代码]
首先,我们加载图像:
System.Drawing.Image image1 = new Bitmap(Server.MapPath("./images/worldmap4.gif"));
Bitmap imgBitmap = new Bitmap(image1);
现在,让我们循环这个二维图像,映射出 phi 和 theta 角,再通过 phi 和 theta 获取笛卡尔3D坐标系,进
行一些旋转以获取3D点,并在目标图像上绘制。
for (int i = 0; i < imgBitmap.Width; i++)
{
for (int j = 0; j < imgBitmap.Height; j++)
{
// map the angles from image coordinates
double theta = Algebra.MapCoordinate(0.0, imgBitmap.Width - 1,
theta1, theta0, i);
double phi = Algebra.MapCoordinate( 0.0, imgBitmap.Height - 1,phi0,
phi1, j);
// find the cartesian coordinates
double x = radius * Math.Sin(phi) * Math.Cos(theta);
double y = radius * Math.Sin(phi) * Math.Sin(theta);
double z = radius * Math.Cos(phi);
// apply rotation around X and Y axis to reposition the sphere
RotX(1.5, ref y, ref z);
RotY(-2.5, ref x, ref z);
// plot only positive points
if (z > 0)
{
Color color = imgBitmap.GetPixel(i, j);
Brush brs = new SolidBrush(color);
Pen pen = new Pen(color);
int ix = (int)x + 100;
int iy = (int)y + 100;
graphics.FillRectangle(brs, ix, iy, 1, 1);
}
}
}
[旋转函数]
事实上,我使用了一个3D的数学库,不过这里,你只需要这三个函数:
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;
}
转自http://www.msproject.cn/Document/MapImage2Dto3D.html