六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 341|回复: 0

x01.EarthRun

[复制链接]

升级  40%

6

主题

6

主题

6

主题

童生

Rank: 1

积分
20
 楼主| 发表于 2013-1-3 15:38:08 | 显示全部楼层 |阅读模式
<div id="cnblogs_post_body">月亮绕着地球转,地球绕着太阳转,一个 TranslateTransform3D + RotationTransform3D 即可搞定。难的是球体(Sphere)绘制。
作为球体,由经度、纬度划分为一小块一小块的。球体的绘制,说白了,就是这一小块一小块的绘制。除上下极点外,每小块由四个点(Point3D)构成,即两个三角形。
现在,只要求出了这些 Point3D,问题即可解决。为简便,不妨设球心 O (0,0,0),半径 r1 。(WPF 3D 坐标:左到右 x 轴,下到上 y 轴,屏幕里到外 z 轴)
如何求球面某经纬度交叉点 A (x,y,z)的 3D 坐标呢?
1. 忽略 z 轴,设角 AOX (纬度偏移)度数为 a,则 x = cos(a); y = sin(a); 同理,z = cos(a);
2. 设经度偏移角度 AOZ 为 b,此时,y 不变。忽略 y 轴,则 x = cos(a)*sin(b); z = cos(a)*cos(b);
即:(cos(a)*sin(b), sin(a), cos(a)*cos(b)) 为 A 3D 坐标。参考代码如下:
<div class="cnblogs_code" >Trangulate<div id="cnblogs_code_open_ae55b94f-540d-4811-8eb8-86e133ade64d" class="cnblogs_code_hide">  protected void Triangulate(DependencyPropertyChangedEventArgs e,            Point3DCollection vertices, Vector3DCollection normals,            Int32Collection indices, PointCollection textures)        {            vertices.Clear();            normals.Clear();            indices.Clear();            textures.Clear();            for (int stack = 0; stack <= Stacks; stack++)            {                double phi = Math.PI / 2 - stack * Math.PI / Stacks;                double y = Radius * Math.Sin(phi);                double scale = -Radius * Math.Cos(phi);                for (int slice = 0; slice <= Slices; slice++)                {                    double theta = slice * 2 * Math.PI / Slices;                    double x = scale * Math.Sin(theta);                    double z = scale * Math.Cos(theta);                    Vector3D normal = new Vector3D(x, y, z);                    normals.Add(normal);                    vertices.Add(normal + Center);                    textures.Add(new Point((double)slice / Slices, (double)stack / Stacks));                }            }            // stack == 0            for (int slice = 0; slice < Slices; slice++)            {                indices.Add(slice + 1);                indices.Add(Slices + 1 + slice);                indices.Add(Slices + 1 + slice + 1);            }            for (int stack = 1; stack < Stacks - 1; stack++)            {                for (int slice = 0; slice < Slices; slice++)                {                    indices.Add(stack * (Slices + 1) + slice);                    indices.Add((stack + 1) * (Slices + 1) + slice);                    indices.Add(stack * (Slices + 1) + slice + 1);                    indices.Add(stack * (Slices + 1) + slice + 1);                    indices.Add((stack + 1) * (Slices + 1) + slice);                    indices.Add((stack + 1) * (Slices + 1) + slice + 1);                }            }            // stack == Stacks - 1            for (int slice = 0; slice < Slices; slice++)            {                int stack = Stacks - 1;                indices.Add(stack * (Slices + 1) + slice);                indices.Add((stack + 1) * (Slices + 1) + slice);                indices.Add(stack * (Slices + 1) + slice + 1);            }        }
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表