Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将平面上的三维坐标转换为新的二维坐标系_Python_Image Processing_Graphics_Geometry_Linear Algebra - Fatal编程技术网

Python 将平面上的三维坐标转换为新的二维坐标系

Python 将平面上的三维坐标转换为新的二维坐标系,python,image-processing,graphics,geometry,linear-algebra,Python,Image Processing,Graphics,Geometry,Linear Algebra,我一直在做一个个人项目,制作方程x^2+y^2+z^2=S的整数解的图像,其中“S”是任意整数 换句话说,我在寻找所有的三维点[x,y,z],其中x,y,z都是完美的平方整数,x+y+z=S 例如,S=2809将具有以下解决方案: [14412961369] [1447291936] [0,02809] 。。。加上上述所有排列(即144+729+1936=1936+729+144) 在我回答我的问题之前,这里有一个关于某些上下文的小切线: 一般方程x+y+z=S的所有解将位于由以下公式定义的

我一直在做一个个人项目,制作方程x^2+y^2+z^2=S的整数解的图像,其中“S”是任意整数

换句话说,我在寻找所有的三维点[x,y,z],其中x,y,z都是完美的平方整数,x+y+z=S

例如,S=2809将具有以下解决方案:

  • [14412961369]
  • [1447291936]
  • [0,02809]
  • 。。。加上上述所有排列(即144+729+1936=1936+729+144)
在我回答我的问题之前,这里有一个关于某些上下文的小切线:

一般方程x+y+z=S的所有解将位于由以下公式定义的二维平面上:

  • A=[S,0,0]
  • B=[0,S,0]
  • C=[0,0,S]
这是一张x+y+z=50的所有解(不仅仅是方点)的图表,以说明该方程的所有解将位于上述ABC定义的同一平面上。请注意,下面三角形的尖端是:[50,0,0]、[0,50,0]和[0,0,50]

回到我的问题: 在找到正方形的解算点之后,我想根据ABC平面将3D解算点转换为2D坐标,A为(0,0),B为最大“x”值,C为最大“y”值。然后我希望将这些解决方案输出到一个图像文件中

我的线性代数知识很贫乏,我一直无法找到一种基于3个非共线点将三维坐标转换为二维平面坐标的方法

我的代码目前是用python编写的,但算法/数学答案也一样好


非常感谢您的帮助

在我看来,你已经可以找到你的
(x,y,z)
点,你的问题是如何将它们投影到平面上

请参阅以了解如何将3d世界投影到您选择的图像平面上

具体来说,您必须将坐标表示为
(x,y,z)
,并将其乘以与需要投射它们的平面正交的相关相机矩阵

这将产生形式为
(x',y',f)
的二维齐次坐标,从中可以通过
(x_投影,y_投影)=(x'/f,y'/f)
获得投影坐标

他是你的朋友

重述:

  • 输入:
    n
    (x,y,z)
  • 使用opencv获取大小为
    (4,3)
    的投影(相机)矩阵
    M
    ,或使用任何工具计算自己
  • 将最后一个尺寸
    1
    添加到所有点,将其作为三维齐次坐标:
    n
    (x,y,z,1)
  • 将所有点乘以矩阵以获得投影点作为二维齐次坐标:
    M*(x,y,z,1)^T
    =
    (x',y',f)
  • 通过
    (x,y)
    =
    (x'/f,y'/f)

  • 好处:你可以把你所有的
    (x,y,z,1)
    点作为列堆叠成
    (4,n)
    矩阵,
    p
    ,整个乘法过程将是
    R=M*p
    ,一个形状
    (3,n)
    的结果矩阵,其列是得到的齐次坐标。

    <,你已经可以找到你的
    (x,y,z)
    点,你的问题是如何将它们投影到平面上

    请参阅以了解如何将3d世界投影到您选择的图像平面上

    具体来说,您必须将坐标表示为
    (x,y,z)
    ,并将其乘以与需要投射它们的平面正交的相关相机矩阵

    这将产生形式为
    (x',y',f)
    的二维齐次坐标,从中可以通过
    (x_投影,y_投影)=(x'/f,y'/f)
    获得投影坐标

    他是你的朋友

    重述:

  • 输入:
    n
    (x,y,z)
  • 使用opencv获取大小为
    (4,3)
    的投影(相机)矩阵
    M
    ,或使用任何工具计算自己
  • 将最后一个尺寸
    1
    添加到所有点,将其作为三维齐次坐标:
    n
    (x,y,z,1)
  • 将所有点乘以矩阵以获得投影点作为二维齐次坐标:
    M*(x,y,z,1)^T
    =
    (x',y',f)
  • 通过
    (x,y)
    =
    (x'/f,y'/f)

  • 奖励:您可以将所有
    (x,y,z,1)
    点作为列堆叠成
    (4,n)
    矩阵,
    p
    ,整个乘法过程将是
    R=M*p
    ,一个形状
    (3,n)的结果矩阵
    R
    其列是生成的齐次坐标。

    我认为Gulzar的答案是正确的,但更多的是围绕渲染(即摄影机和齐次坐标)进行的。然而,我确实想出了如何做我想做的事

    import ast
    import math
    import matplotlib.pyplot as plt
    
    def dot_3d(a, b):
        return (a[0]*b[0])+ (a[1]*b[1]) + (a[2]*b[2])
    
    def minus_3d(a, b):
        return [a[0] - b[0], a[1] - b[1], a[2] - b[2]]
    
    def midpoint_3d(a, b):
        return [(a[0] + b[0])/2, (a[1] + b[1])/2, (a[2] + b[2])/2]
    
    def normalize_3d(vec):
        magnitude = math.sqrt(vec[0]**2 + vec[1]**2 + vec[2]**2)
        return [vec[0]/magnitude, vec[1]/magnitude, vec[2]/magnitude]
    
    X = 2809
    
    A = [X, 0, 0]
    B = [0, X, 0]
    C = [0, 0, X]
    
    S = set([])
    for a in range(X+1):
        if int(math.sqrt(a))**2 == a:
            for b in range(X+1):
                if int(math.sqrt(b))**2 == b:
                    for c in range(X+1):
                        if int(math.sqrt(c))**2 == c and a + b + c == X:
                            S.add(str([a, b, c]))
    S = list(S)
    
    origin = A
    normal = normalize_3d([X/3, X/3, X/3])
    ax1 = normalize_3d(minus_3d(B, A))
    ax2 = normalize_3d(minus_3d(C, midpoint_3d(A, B)))
    
    answers = []
    
    for point_str in S:
        point = ast.literal_eval(point_str)
        x = dot_3d(ax1, minus_3d(point, origin))
        y = dot_3d(ax2, minus_3d(point, origin))
        answers.append([x, y])
    
    plt.scatter([p[0] for p in answers], [p[1] for p in answers])
    plt.xlabel('x')
    plt.ylabel('y')
    plt.show()
    
    开始绘制三维坐标图:

    ABC平面上的“投影”坐标:

    我认为古尔扎的答案是正确的,但更多的是围绕渲染(即摄影机和同质坐标)进行的。然而,我确实想出了如何做我想做的事

    import ast
    import math
    import matplotlib.pyplot as plt
    
    def dot_3d(a, b):
        return (a[0]*b[0])+ (a[1]*b[1]) + (a[2]*b[2])
    
    def minus_3d(a, b):
        return [a[0] - b[0], a[1] - b[1], a[2] - b[2]]
    
    def midpoint_3d(a, b):
        return [(a[0] + b[0])/2, (a[1] + b[1])/2, (a[2] + b[2])/2]
    
    def normalize_3d(vec):
        magnitude = math.sqrt(vec[0]**2 + vec[1]**2 + vec[2]**2)
        return [vec[0]/magnitude, vec[1]/magnitude, vec[2]/magnitude]
    
    X = 2809
    
    A = [X, 0, 0]
    B = [0, X, 0]
    C = [0, 0, X]
    
    S = set([])
    for a in range(X+1):
        if int(math.sqrt(a))**2 == a:
            for b in range(X+1):
                if int(math.sqrt(b))**2 == b:
                    for c in range(X+1):
                        if int(math.sqrt(c))**2 == c and a + b + c == X:
                            S.add(str([a, b, c]))
    S = list(S)
    
    origin = A
    normal = normalize_3d([X/3, X/3, X/3])
    ax1 = normalize_3d(minus_3d(B, A))
    ax2 = normalize_3d(minus_3d(C, midpoint_3d(A, B)))
    
    answers = []
    
    for point_str in S:
        point = ast.literal_eval(point_str)
        x = dot_3d(ax1, minus_3d(point, origin))
        y = dot_3d(ax2, minus_3d(point, origin))
        answers.append([x, y])
    
    plt.scatter([p[0] for p in answers], [p[1] for p in answers])
    plt.xlabel('x')
    plt.ylabel('y')
    plt.show()
    
    开始绘制三维坐标图:

    ABC平面上的“投影”坐标:

    这个问题至少有3个不同的问题。请将您的问题集中到“我的输入是”和“期望的输出”的形式,以便我们可以帮助您better@Gulzar不确定你还看到了哪些问题。输入:设置为o