将平面上的3D坐标转换为新的2D坐标系

问题描述

我一直在从事一个个人项目,以生成方程x ^ 2 + y ^ 2 + z ^ 2 = S的整数解的图像,其中'S'是任何整数。

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

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

  • [144,1296,1369],
  • [144,729,1936],
  • [0,0,2809]
  • ...加上上述所有排列(即144 + 729 + 1936 = 1936 + 729 + 144)

在我开始提问之前,这里是一些上下文的小切线:

一般方程x + y + z = S的所有解都将位于以下定义的2D平面上:

  • 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 plane

回到我的问题: 找到平方解点后,我想将3D解点转置为基于ABC平面的2D坐标,其中A为(0,0),B为最大'x'值,C为最大'y'值。然后,我希望将这些解决方输出到图像文件

我的线性代数知识很少,而且我找不到基于3个非共线点将3D坐标转换为2D平面坐标的方法

我的代码当前在python中,但是算法/数学答案也一样!

非常感谢您的帮助!

解决方法

正如我所看到的,您已经找到了<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/home" android:title="BlaBlaBla" /> ... 个点,而您的问题是关于将它们投影到飞机上的方法。

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

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

这将产生二维(x',y',f)形式的齐次坐标,您将可以通过(x_projected,y_projected) = (x'/f,y'/f)来获得投影坐标。

homogeneous coordinates是你的朋友。

回顾:

  1. 输入:n (x,z)
  2. 使用opencv获取大小为M的投影(相机)矩阵(4,3),或使用任何工具进行计算。
  3. 在所有点上添加最后一个维度1,以将其作为3d齐次坐标:n(x,1)
  4. 将所有点乘以矩阵以获得投影点,作为二维齐次坐标:M * (x,1)^T = (x',f)
  5. 通过n = M来获取(x,y)实际2d投影坐标(相对于(x'/f,y'/f)矩阵定义的相机中心)

奖金:您可以将所有(x,1)点作为列堆叠到(4,n)矩阵P中,整个乘法过程将是R = M * P,结果矩阵{形状为R的{​​1}},其列为所得齐次坐标。

,

我认为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]
B = [0,X,0]
C = [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,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()

绘制的3D起始坐标: enter image description here

“投影”在ABC平面上的坐标: enter image description here