我们在 #python channel 中尝试了很长一段时间如何使用 sympy 从 View 矩阵中计算眼睛/目标/向上向量。一种可能的方法是:
from sympy import *
from pprint import pprint
v1, v2, v3, v4 = symbols('v1 v2 v3 v4')
v5, v6, v7, v8 = symbols('v5 v6 v7 v8')
v9, v10, v11, v12 = symbols('v9 v10 v11 v12')
v13, v14, v15, v16 = symbols('v13 v14 v15 v16')
V = Matrix([
[v1, v2, v3, v4],
[v5, v6, v7, v8],
[v9, v10, v11, v12],
[v13, v14, v15, v16],
])
u1, u2, u3 = symbols('u1 u2 u3', real=True)
t1, t2, t3 = symbols('t1 t2 t3', real=True)
e1, e2, e3 = symbols('e1 e2 e3', real=True)
U = Matrix([u1, u2, u3])
T = Matrix([t1, t2, t2])
E = Matrix([e1, e2, e3])
def calculate_view_matrix(up, eye, target):
zaxis = (eye - target).normalized()
xaxis = up.cross(zaxis).normalized()
yaxis = zaxis.cross(xaxis)
orientation = Matrix([
[xaxis[0], yaxis[0], zaxis[0], 0],
[xaxis[1], yaxis[1], zaxis[1], 0],
[xaxis[2], yaxis[2], zaxis[2], 0],
[0, 0, 0, 1],
])
translation = Matrix([
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[-eye[0], -eye[1], -eye[2], 1],
])
return orientation * translation
print(V - calculate_view_matrix(U, E, T))
s = solve([
V - calculate_view_matrix(U, E, T),
U.norm() - 1,
T.norm() - 1],
[u1, u2, u3, t1, t2, t3, e1, e2, e3])
print(s)
但由于某种原因,该脚本已经运行了约 20 分钟,而 sympy 到目前为止还无法给出任何解决方案。
另一种尝试也试图将上述一般问题简化为更简单的问题,例如如何计算向上向量?
在更简单的上下文中,问题定义应该是这样的:
u,z,x 是构成 orthonormal basis 的 3d 向量.z, x 是常数向量u 是未知向量求解这个的方程式:
u.cross(z).normalized() - x
如果您尝试像这样解决上述通用方程的一个简单特例...
from sympy import *
u1,u2,u3=symbols('u1 u2 u3', real = True)
x=Matrix([1,0,0])
z=Matrix([0,0,1])
u=Matrix([u1,u2,u3])
print(solve(u.cross(z).normalized() - x, u))
你会得到 NotImplementedError: could not solve u2 - Abs(u2)。
NS:事实是,为了从 View 矩阵中提取输入,计算矩阵的函数必须是单射或双射的,否则初始信息将丢失。如果您不添加任何约束,上述函数绝对不是单射的,因为在使用归一化操作的那一刻,该函数自动不再是单射的,例如:
a) normalize(x) = x/|x|
b) To prove normalize is injective then normalize(a)=normalize(b) should give a=b
c) normalize(a)=normalize(b) => a/|a|=b/|b| , which is not true then normalize is not injective
当然,这可以简单地证明只是说无限向量可以提供相同的归一化向量。
这就是为什么向 calculate_view_matrix 添加了一些约束的原因。即:U.norm() - 1,T.norm() - 1。从理论上讲,这应该使 calculate_view_matrix 成为单射的...(或不是 :))
所以主要问题是,如何正确约束/修改 calculate_view_matrix 以便它可以计算出 View 矩阵的眼睛/目标/向上向量?
最佳答案
除了打字错误(T = Matrix([t1, t2, t2]))之外,从 View 矩阵返回的 Ansatz、眼睛和目标向量还有几个缺陷:
v1, v2, ..., v16 中只能选择 6 个(或多或少是任意的),其他值是相关的或以任何方式确定(例如 v4 = v8 = v12 = 0, v16 = 1, v3**2 = 1 - v1**2 - v2**2, ... ).所以一般来说,矩阵差分的方程是矛盾的。U.norm() - 1 = 0 时,向上矢量 U 也可以取无限多个值(一个角度未确定)。要将 U 的可能解减少到有限多种情况,可以添加条件 U*(E-T) = 0。T.norm() - 1 = 0 是错误的。可以/应该要求长度为 1 的是 T - E(视角方向)。总而言之,我没有找到修复 Ansatz s.t. 的方法。 U, E, T 可以使用方程式和 sympy 从 View 矩阵计算。但是 U, E, T 可以很容易地从 View 矩阵中提取出来:
U(满足上述要求)-E可以从最后一行开始读取E - T在 sympy/Python 代码中:
def calculate_up_eye_target(viewMat):
eye = -viewMat[3,0:3].T
target = eye - viewMat[0:3,2]
up = viewMat[0:3,1]
return up, eye, target
关于python - 如何使用 sympy 从 View 矩阵中提取眼睛/目标/向上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43706865/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t