创建一个追踪摄像机(2)

为了生成曲线,函数需要通过4个在沿着重量值在0和1之间的路径上连贯的位置。由于重量在这些2个值之间增加,曲线返回在更远的路径上的坐标。

当所提供的重量值为0,曲线将返回正确的坐标在第二个输入坐标。当所提供的重量值为1,曲线将返回一个准确的坐标在第三个输入位置。然而,所有4个值在这些计算中来使用, 来确保在第二个和第三个位置之间的平滑路径,并同样向前进到下一组运行点。

这个可以使用图表来举例说明,在图所示。如果使用点0,1,2和3来计算曲线,重量在0.0,由此产生的位置会是1。如果重量增加到1.0,曲线坐标轨迹将沿着在点1和点2之间的线,当重量到达1.0,将到达点2。注意,从这个点的,曲线坐标没有返回值在线上,朝点0或点3,即使它们将通过曲线函数:这些外部点仅使用来计算在中心的2个点之间的曲线角度。

image

一旦重量到达1.0,曲线可以移动到下一组点,进入点1,2,3和4。然后重量再次从0.0增加到1.0后,导致计算的坐标,沿着点2和点3之间的线。

从这组点,它不可能返回在点0和1之间的曲线坐标,或者在点4和5之间(图表中显示灰色),有要处理的路径这些部分的不足外部点。

通过在点到点之间的移动路径,一个平滑曲线可以减少,穿过所有定义的位置。这一切在三维空间也能做的很好。

提示:当定义一个路径,别忘记它将采取完全相同的大量时间在每一个连贯的路径点之间移动。因此,你应该尝试去确保点近似等距。点有不同于其它的大的差距将导致更快的移动,在固定时间间隔内穿过增加的距离,点更接近在一起将导致移动缓慢,因为少距离必须要去移动。

为了创建一个封闭的路径,允许飞机去循环,无缝的回到它最初的点再重新开始,我们必须确保最终的曲线的三个点与三个点的第一个相同。当三个点的重量到达1.0时,曲线坐标将终于到达回正确的在移动路径上的点1的位置,允许整个路径从再次从最开始就可以被跟踪。

我们在PaperPlaneObject代码中实现它,通过存储2个类级变量,一个int值称为_splineIndex,它定义4个点的第一个索引来使用曲线计算;一个浮点值称为_splineWeight,它允许我们来沿着曲线在定义点之间穿过路径。

在Update函数中,我们添加一个小的总额到_splineWeight变量中。如果它到达或超过1.0,我们要将它减1.0,并增加_splineIndex。如果_splineIndex通过移动路径的最后的数组点,它重新设置回开始。这些更新沿着曲线移动飞机,并当它到达它的移动路径的重点后,重新设置回起点。

在这些更新模式下,我们调用GetPlanePosition函数来执行曲线计算,并返回最终飞行坐标。这个函数,期望曲线索引和曲线重量值来作为参数来传递,下面代码将描述。

private Vector3 GetPlanePosition(int splineIndex, float  splineWeight)
{Vector3 ret;// If the  weight  exceeds 1,  reduce by 1 and move  to  the  next  index if (splineWeight > 1){splineWeight  -=  1;splineIndex += 1;}// Keep  the  spline index  within the  array  boundssplineIndex = splineIndex %   _movementPath.Length;// Calculate  the  spline positionret = Vector3.CatmullRom(_movementPath[splineIndex],_movementPath[(splineIndex + 1)  %   _movementPathLength],_movementPath[(splineIndex + 2)  %   _movementPathLength],_movementPath[(splineIndex + 3)  %   _movementPathLength], splineWeight);return ret;
}

这代码首先检查曲线重量是否大于1。如果是,它就减去1并且切换到下一个曲线索引(我们将一会儿看到这个原因)。其次是检查循环曲线索引,是否它超过_movementPath数组项目的界限。

曲线坐标然后会简单的计算,通过传递4个矢量坐标和曲线重量到Vector3.CatmullRom函数。注意,然而,因为我们在曲线索引指上使用指数运算符,如果它们超过数组长度,它们会循环回到最初的开始。这个运算允许我们去实现我们的闭合环路(要求重复前3个点),而不必实际在数组中重复它们:它们只是一开始就重复使用,当到达数组末尾时。

随着有能力手动去计算飞行坐标,我们现在可以设置飞行的坐标和沿着轨迹去平滑移动。这是好的开始,但这是非常明显的可视化问题,当它在运动时:飞行总是对着同一个方向。当然,总是朝着移动的方向(纸飞机通常来说不会侧面飞行的很好)。

幸运的是,这是非常容易让飞行看上去它是正在飞行的。我们需要做的第一件事是计算另一个飞行坐标,仅远一点沿着轨迹。我们通过调用GetPlanePosition函数,在1秒钟内来完成它,这个时候添加0.1到曲线重量中。此外的原因是GetPlanePosition函数检查是否重量超过1.0,因为这一秒可以引起溢出的发生。

第二个调用允许我们看到现在在哪里飞行,下一秒后将会在哪里。飞行的方向必须从这些点到下一秒所在的点,因为它的轨迹是移动的。因此我们需要一个旋转飞机的方法以便它面朝从第一个位置到下一个秒所要到的位置。

这个旋转可以使用另一个便利的静态的矩阵函数来完成:CreateWorld。CreateWorld函数创建一个世界矩阵(它是最后我们要在每一个对象的Update方法中尝试去做的)以便它放置在特别的位置上,面对特别的方向。这就是我们所需要的:位置是我们已计算出来的第一条曲线,方向从这到下一条曲线点。

通过从下一个位置减去当前位置来简单计算方向。由此产生的矢量准备作为参数传递给CreateWorld。

有一个小问题任然存在:飞机是持续向一侧飞行的,因为它的一侧已经在SketchUp模式下定义了。要修正这个问题,矩阵计算后,我们简单旋转90度角来旋转它。

计算位置和飞行方向的完整代码如下代码所示。

// Calculate  the  current position and store  in the  Position property
Vector3 Position = GetPlanePosition(_splineIndex, _splineWeight);// Calculate  the  next  position too  so we  know  which way we  are moving
Vector3 nextPosition = GetPlanePosition(_splineIndex, _splineWeight  + 0.1f);// Find the  movement  direction
Vector3 delta  = nextPosition - Position;// Create the  world  matrix  for the  plane
Transformation  = Matrix.CreateWorld(Position, delta,  Vector3.Up);
// The plane needs to  be rotated 90 degrees   so that  it points
// forward, so apply  a rotation
ApplyTransformation(Matrix.CreateRotationY(MathHelper.ToRadians(-90)));

最终结果是我们有一个平滑的逼真的在房屋间围绕场景飞行。你可以通过运行ChaseCam工程看到实际效果—最初的视图使用一个不会追逐飞行轨迹的相机,而是慢慢的环绕这个场景,允许简单的看到飞行轨迹。

转载于:https://www.cnblogs.com/appleseeker/archive/2012/05/24/e5889be5bbbae4b880e4b8aae8bfbde8b8aae69184e5838fe69cba2.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/260789.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Xcodebuild自动打包

#! /bin/bash #firtoken 29b441056e1e17c984cb32fadadsdddd shell_dirdirname $0 TARGET_NAME"SmartLock" DIR_PATH/Users/用户名/Desktop/SmartLock SIGN"iPhone Distribution:******" PROFILE"66d127d6-7963-4c20-ac8b-47e4f0fe8742" TEMP_DIR…

第3章 Python 数字图像处理(DIP) - 灰度变换与空间滤波12 - 空间域滤波基础 - 卷积运算(numpy 实现的三种卷积运算)

这篇文章比较长,请耐心看空间域滤波基础线性滤波可分离滤波器核空间域滤波和频率域滤波的一些重要比较如何构建空间滤波器第一种卷积方法(公式法)第二种卷积的方法(可分离核)第三种方法(img2col)这是分离核…

hdu_1861_游船出租_201402282130

游船出租 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7238 Accepted Submission(s): 2411 Problem Description 现有公园游船租赁处请你编写一个租船管理系统。当游客租船时,管理员输入船号并按…

acer清理工具 clear下载_SolidWorks绿色版下载-SolidWorks完全清理工具v1.0免费版

SolidWorks完全清理工具(SWCleanUninstall)是一款绿色免费的SolidWorks完全卸载工具。很多SolidWorks安装不成功都是因为之前安装错误做成软件残留。这款工具可以完全清理很多SolidWorks留下的注册表垃圾。软件核心功能1、SWCleanUninstall可以直接删除电脑上的SolidWorks软件2…

ZOJ1221 Risk 图形的遍历

一开始做图形遍历的题都是用链表做的&#xff0c;这次用数组体会到了方便但就是有点浪费。 不过题目给的内存限制已经足够了。 View Code 1 #include<cstdio>2 #include<cstdlib>3 #include<cstring>4 #include<queue>5 #include<iostream>6 7 …

Android 从AndroidManifest获取meta-data

语法如下&#xff1a; <meta-data android:name"string"android:resource"resource specification"android:value"string" /><meta-data>标签可以作为子标签&#xff0c;可以被包含在<activity>、<application> 、<s…

trim()函数

参数string&#xff1a;string类型&#xff0c;指定要删除首部和尾部空格的字符串返回值String。 函数执行成功时返回删除了string字符串首部和尾部空格的字符串&#xff0c;发生错误时 返回空字符串&#xff08;""&#xff09;。 如果参数值为null时&#xff0c;会抛…

第3章 Python 数字图像处理(DIP) - 灰度变换与空间滤波13 - 平滑低通滤波器 -盒式滤波器核

这里写目录标题平滑&#xff08;低通&#xff09;空间滤波器盒式滤波器核平滑&#xff08;低通&#xff09;空间滤波器 平滑&#xff08;也称平均&#xff09;空间滤波器用于降低灰度的急剧过渡 在图像重取样之前平滑图像以减少混淆用于减少图像中无关细节平滑因灰度级数量不…

python中str用法_python数据类型之str用法

1、首字母大写 语法&#xff1a;S.capitalize() ->str title "today is a good day"title_catitle.capitalize() print(title_ca) 结果&#xff1a;today is a good day 2、大写转小写 1 语法&#xff1a;S.casefold() ->str2 3 title "TODAY is a GOOD …

WPF 窗体设置

WPF 当窗体最大化时控件位置的大小调整&#xff1a; View Code 1 <Window x:Class"WpfApplication1.MainWindow"2 xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"3 xmlns:x"http://schemas.microsoft.com/wi…

Git实践

Git是什么自不必说。Git和gitlab安装和实践在后边的俩篇中会写。本篇仅重点写Git自动部署。Git同样有Hooks,可以用于各种需求。可以控制提交commit名称&#xff0c;可以控制代码规范&#xff0c;也当然包含以下要介绍的自动部署&#xff0c;也不仅包含这些。Git自动部署简单的思…

第3章 Python 数字图像处理(DIP) - 灰度变换与空间滤波14 - 平滑低通滤波器 -高斯滤波器核的生成方法

目录平滑&#xff08;低通&#xff09;空间滤波器低通高斯滤波器核统计排序&#xff08;非线性&#xff09;滤波器平滑&#xff08;低通&#xff09;空间滤波器 平滑&#xff08;也称平均&#xff09;空间滤波器用于降低灰度的急剧过渡 在图像重取样之前平滑图像以减少混淆用…

易经0

--- 阳爻 - - 阴爻 从下往上 画爻 (yao) 三画卦 --> 2^38 (八卦) 那天有空用程序 解析一下 六画卦 --> 2^664(卦) 卦形记忆歌&#xff1a;宋代朱熹的《周易本义》写了《八卦取象歌》帮人记卦形&#xff1a; 乾三连&#xff0c;坤六断&#xff1b;震仰盂&#xff0c;艮覆碗…

python3.7怎么安装turtle_python怎么安装turtle

turtle库是Python语言中一个很流行的绘制图像的函数库&#xff0c;想象一个小乌龟&#xff0c;在一个横轴为x、纵轴为y的坐标系原点&#xff0c;(0,0)位置开始&#xff0c;它根据一组函数指令的控制&#xff0c;在这个平面坐标系中移动&#xff0c;从而在它爬行的路径上绘制了图…

强制html元素不随窗口缩小而换行

<style> div{ white-space:nowrap; } </style> 强制div内的元素不随窗口缩小而换行 本文出自 “点滴积累” 博客&#xff0c;请务必保留此出处http://tianxingzhe.blog.51cto.com/3390077/1679366

静态变量、方法

static 变量---所有对象共享一个变量&#xff08;全局变量区&#xff09;&#xff0c;无需构造---概念上和.net相同所有对象共享一个变量的实质&#xff1a;声明时&#xff1a;堆区存放一个地址&#xff0c;地址指向全局变量区。然后当类对象声明时&#xff0c;只是在堆区中为自…

python语言是机器语言_Python解释器:源代码--字节码--机器语言

"一个用编译性语言比如C或C写的程序可以从源文件&#xff08;即C或C语言&#xff09;转换到一个你的计算机使用的语言&#xff08;二进制代码&#xff0c;即0和1&#xff09;。这个过程通过编译器和不同的标记、选项完成。当你运行你的程序的时候&#xff0c;连接/转载器软…

第3章 Python 数字图像处理(DIP) - 灰度变换与空间滤波15 - 锐化高通滤波器 -拉普拉斯核(二阶导数)

目录锐化&#xff08;高通&#xff09;空间滤波器基础 - 一阶导数和二阶导数的锐化滤波器二阶导数锐化图像--拉普拉斯锐化&#xff08;高通&#xff09;空间滤波器 平滑通过称为低通滤波类似于积分运算锐化通常称为高通滤波微分运算高过&#xff08;负责细节的&#xff09;高频…

Debian on VirtualBox下共享win7文件夹设置

借用&#xff1a;http://www.dbasoul.com/2010/695.html 1. 安装增强功能包(Guest Additions) 参考文档&#xff1a;Debian下安装VirtualBox增强功能2. 设置共享文件夹 重启完成后点击”设备(Devices)” -> 共享文件夹(Shared Folders)菜单&#xff0c;添加一个共享文件夹&a…

第四周作业

1、复制/etc/skel目录为/home/tuser1&#xff0c;要求/home/tuser1及其内部文件的属组和其它用户均没有任何访问权限。cp -r /etc/skel/ /home/tuser1/chmod -R go--- /home/tuser1/2、编辑/etc/group文件&#xff0c;添加组hadoop。vim /etc/group G, o, hadoop:x:501, esc, …