c-在等轴测投影中将三维坐标转换为二维坐标



我在将3D坐标转换为2D时遇到问题,然后在C.中打印等轴测投影中的所有点

我试过这个:

u = x / z;
v = y / z;

但是当z=0时,我的函数进入一个无限循环。

我也在谷歌上找到了一些东西,但这对负Z不起作用(我想要Z>0时的凸起和Z<0时的凹陷)

以下是我的工作方式。我的函数得到一个看起来像的文件

0 0 0 0 0 0 0 0 0 0
0 9 9 9 9 9 9 9 9 0
0 9 9 9 9 9 9 9 9 0
0 9 9 9 -5 -5 9 9 9 0
0 9 9 9 -5 -5 9 9 9 0
0 9 9 9 -5 -5 9 9 9 0
0 9 9 9 -5 -5 9 9 9 0
0 9 9 9 9 9 9 9 9 0
0 9 9 9 9 9 9 9 9 0
0 0 0 0 0 0 0 0 0 0

数字表示z坐标,原点(0;0;0)在左上角。

听起来像是在混合概念。只有当您认为3D原点是您的相机,z=1平面是您的屏幕时,除以第三坐标才有意义。在这种情况下,z=0的点被投影到无穷大。通常,您有一个视图截头体来剪裁这样的无限坐标。如果您的输入被期望为z=0,那么这是不可行的。

在任何情况下,它都不是等角的,因为z轴扮演的角色与所有其他轴不同。等距投影是平行投影的一种特殊情况,而你的除法表示中心投影,除非它是平面投影变换后的去均匀化步骤。

对于等距投影,我建议您尝试以下方法:

u = x*cos(α) + y*cos(α+120°) + z*cos(α-120°)
v = x*sin(α) + y*sin(α+120°) + z*sin(α-120°)

尽管对于C,你必须转换成弧度。α会旋转你的视图,选择你想对齐的东西。如果你选择α作为30°的倍数,你会得到相当好的数字,只涉及一个简单的平方根。sin/cos对简单地描述了彼此相距120°的三个单位长度的矢量。使用这些作为三维单位向量的图像。如果你愿意的话,你也可以把它写成矩阵乘以向量乘法。

以下是维基百科页面上关于等距投影的数学方程的非优化实现

它可以归结为以下功能:

int toIsometric2D(double x, double y,double z, double *u, double*v){
    *u=(x-z)/sqrt(2);
    *v=(x+2*y+z)/sqrt(6);
    return 0;
}

编译以下代码:gcc main.c -o main -lm

#include <stdio.h>
#include <math.h>

int toIsometric2D(double x, double y,double z, double *u, double*v){
    *u=(x-z)/sqrt(2);
    *v=(x+2*y+z)/sqrt(6);
    return 0;
}
int main(){
    int n=10;
    double z[n][n];
    int i,j;
    for(i=0;i<9;i++){
        for(j=0;j<9;j++){
            z[i][j]=0;
        }
    }
    for(i=2;i<8;i++){
        for(j=2;j<8;j++){
            z[i][j]=9;
        }
    }
    for(i=4;i<6;i++){
        for(j=4;j<6;j++){
            z[i][j]=-5;
        }
    }
    double u[n][n];
    double v[n][n];
    for(i=0;i<9;i++){
        for(j=0;j<9;j++){
            toIsometric2D(i, j,z[i][j], &u[i][j],&v[i][j]);
        }
    }
    //print to file -> gnuplot
    FILE* fp;
    fp=fopen("data.dat","w");
    for(i=0;i<9;i++){
        for(j=0;j<9;j++){
            fprintf(fp,"%g %g %gn",u[i][j],v[i][j],z[i][j]);
        }
    }
    fclose(fp);
}

它生成一个包含u v z的文件data.dat。它可以由gnuplot软件显示,方法是按照gnuplot中的第一个答案:当第三列等于零时,如何使点变成一种颜色,否则变成另一种颜色?gnuplot命令是:

plot[-7:10][-5:15] "data.dat" u 1:2:( $3 ) with points pt 7 ps 3 palette

最新更新