作为相机系列,此处先温习一下前期涉及到Cesium中Camera的两个概念(系列文章可参考我前面发的“Cesium中的相机–”系列)。
Cesium中,世界坐标系就是地球的WGS84系,也即地球固连坐标系(Earth Fiexed),在此坐标中定义相机的位置与观测方位。
相机坐标系见下图(使用Hubble望远镜示意相机),在Camera对象中,通常用三个矢量来表示:Up、Right和Direction,这三个方向确定了相机的观测方位。Up、Right、Direction与相机坐标系(视图坐标系)XYZ三轴的关系为:
X=Direction
Y=Left
Z=Up

在Cesium中,常使用Heading/Pitch/Roll三个参数来表示相机相对某坐标系的姿态:
温顾了上述两个知识点,下面直接给出SetView的定义

Camera中的SetView函数用来设置相机的位置和方位的。
相机位置由destination指定,通常使用三维笛卡尔坐标(Cartesian3)来确定,此坐标默认为世界坐标系(即WGS84系)下,显然,destination距离地球越远,则视场内地球越小。
相机的方位由orientaiton参数指定,有两种方式:1)HeadingPitchRoll三个参数;2)DirectionUp两个参数。
下图左图给出了Cesium中SetView函数时,相机的初始方位:

因此,基于相机的初始方位,可以使用HeadingPitchRoll三个参数来表示相机的具体方位,具体转换过程见上面有关HeadingPitchRoll的阐述。
简单举个例子,如果我们想要相机看向地心,那么为上图右图所示。可知,只要将相机从初始方位沿着Y轴旋转90°(对应的Pitch角度为-90°)即可。
当然,使用Direction和Up两个参数也可以指定相机的方位,简介明了,但是需要给出两个具体的矢量方向。
下面直接以代码给出几个示例:
// 1. Top-Down视角。此处仅设置相机位置,函数内部将Pitch设置为-90°,实现向地心看的效果
viewer.camera.setView({
destination : Cesium.Cartesian3.fromDegrees(-117.16, 32.71, 15000.0)
});
// 2 采用Heading,Pitch,roll参数 设置相机方位
viewer.camera.setView({
destination : Cesium.Cartesian3.fromDegrees(0, 0, 10000000), //赤道上空1000km高度
orientation: {
heading : Cesium.Math.toRadians(90.0), // 相机方向指向当地东向
pitch : Cesium.Math.toRadians(-90), // 再将相机方向转向地心,此时Up方向指向当地东向
roll : 0.0
}
});
// 3. 采用Heading,Pitch,roll参数设置相机方位,相机位置没有设置,则采用原来的位置!
viewer.camera.setView({
orientation: {
heading : Cesium.Math.toRadians(90.0), // 相机方向指向当地东向
pitch : Cesium.Math.toRadians(-90), // 再将相机方向转向地心,此时Up方向指向当地东向
roll : 0.0
}
});
// 4. 相机位置使用矩形定义,相机方位为缺省设置(内部pitch=-90°),实现看地心效果
viewer.camera.setView({
destination : Cesium.Rectangle.fromDegrees(west, south, east, north)
});
// 5. 使用direction和up矢量方向直接定义相机的方位
viewer.camera.setView({
destination : Cesium.Cartesian3.fromDegrees(-122.19, 46.25, 5000.0), // 相机的位置
orientation : {
direction : new Cesium.Cartesian3(-0.042312, -0.201232, -0.978629), //相机视线方向矢量(WGS84系下)
up : new Cesium.Cartesian3(-0.479345, -0.855321, 0.1966022) //相机的up方向矢量(WGS84系下)
}
});
setView函数直接确定了相机在世界坐标系的位置,而且相机的方向可以任意指定。但是在Cesium中,我们常常有一种跟随对象的视角,也就是相机始终跟随运动的对象(如下图的飞行中的龙飞船)。鼠标无论怎么调整视角,相机的方向始终对着龙飞船,也就是说相机的参考系不再是世界坐标系了,而是飞船局部坐标系。

lookAtTransform函数的定义见下图,它的主要功能是:设定一个局部的参考系,让相机始终朝着局部参考系的原点。

在上面定义中,两个参数的说明如下,可结合下图来看。

下面直接以代码给出示例:
// 在赤道上零经度上空一点,局部坐标系为:east-north-up坐标系,X:当地东向,Y:当地北向,Z:当地天顶方向,即世界坐标系的x方向
// transform为局部坐标系到世界坐标系的齐次转换矩阵(包含旋转和平移)
const transform = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(0, 0, 10000000));
// 相机设置在局部坐标系的(0,0,1000)处,相机的视线方向指向局部坐标系零点,本例中,也就是从局部坐标系的Z轴向原点看,在世界坐标系下看就是向地心看
// 注意,由于此时视线方向与Z轴重合,所以程序内部将up方向设置为局部坐标系的Y方向,本例中也就是世界坐标系的Z方向。见下图示意。
var offset = new Cesium.Cartesian3(0, 0, 1000);
viewer.camera.lookAtTransform(transform, offset);
下图为上个例子的代码对应的示意图

另一个例子就是地球惯性系的视角,也即地球在自转的效果,参见下面代码,这个也是Cesium官方给出的例子
// 根据当前场景时间实时计算视角
// 此函数被注册到scene.preRender事件中
function icrf(scene, time) {
// 不是3D窗口,直接返回
if (scene.mode !== Cesium.SceneMode.SCENE3D) {
return;
}
// 本例中,相机的局部坐标系就是地球惯性系,原点和世界坐标系重合,因此只有旋转,没有平移
// 计算当前时刻,地球惯性系(icrf)到固定系(Fixed,也就是世界坐标系WGS84)的转换矩阵
var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time);
// 此处判断icrfToFixed是因为有可能上面代码返回为undefined
if (Cesium.defined(icrfToFixed)) {
// Maxtrix4形式,注意,此处没有平移,因为原点重合
var transform = Cesium.Matrix4.fromRotationTranslation(icrfToFixed);
// 当前相机的位置(相对局部坐标系的位置)
var offset = Cesium.Cartesian3.clone(scene.camera.position);
scene.camera.lookAtTransform(transform, offset);
}
}
// 每次场景更新时都调用函数icrf调整视角
viewer.scene.preRender.addEventListener(icrf);
通过以上两个例子可知,我们只要提供了想要的局部坐标系到世界坐标系的齐次转换矩阵(Matrix4形式),那么就可以将相机局限在我们想要的局部坐标系中!!
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar