问题描述
我一直在从事一个个人项目,以生成方程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]
回到我的问题: 找到平方解点后,我想将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是你的朋友。
回顾:
- 输入:
n
(x,z)
分 - 使用opencv获取大小为
M
的投影(相机)矩阵(4,3)
,或使用任何工具进行计算。 - 在所有点上添加最后一个维度
1
,以将其作为3d齐次坐标:n
点(x,1)
- 将所有点乘以矩阵以获得投影点,作为二维齐次坐标:
M * (x,1)^T
=(x',f)
- 通过
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()