JavaFX逆运动学库2.0

这是第一篇讲解javafx-ik的基础教程, javafx-ik是JavaFX的逆运动学库。 该库的源代码可以从GitHub下载。

什么是

单骨

图1:单骨

骨骼是使用javafx-ik库进行逆运动学的基本基础。 骨骼具有一定长度和关节,骨骼可以围绕该关节旋转。 具有关节的一端称为骨头,另一端称为尾端。 图1显示了一根骨头,其头,尾和长度。

在库javafx-ik中 ,骨骼类似于类Bone 。 要对其进行初始化,必须至少传递长度,但通常在构造过程中还要设置角度。 上面的代码示例设置了一条长度为50且旋转为0的骨骼,这意味着它将水平指向右侧。

// Adding bone b2 to the children of bone b1
b1.getChildren().add(b2);

查看Gist上的代码。

组装骨头

组装两个骨头

图2:组装两个骨骼

可以组装骨骼来定义动画对象的骨架。 通过将一根骨头b1的尾巴连接到另一根骨头b2的头部来链接两根骨头。 骨骼b1称为骨骼b2的父级,骨骼b2称为骨骼b1的子级。 图2显示了两个相连的骨骼b1b2

Bone类为结构提供两个属性。 只读属性parent店骨骼的父,物业孩子是所有儿童骨骼的ObservableList。 以下代码片段显示了如何连接两个骨骼b1b2

// Adding bone b2 to the children of bone b1
b1.getChildren().add(b2);

查看Gist上的代码。

假人的结构

图3:假人的结构

只读属性角度定义了骨骼及其父骨骼的延伸之间的旋转。 值0表示一条直线,值180表示子骨骼与其父骨骼重叠,但指向相反的方向。 尽管让父母和孩子在骨骼的骨骼上施加顺序,但通常没有区别,哪个骨骼是父母,哪个骨骼是孩子。 通过重复链接骨骼对象的头和尾,可以创建链。 这种简单的结构用于毛毛虫样品中。 复杂对象是使用骨骼树定义的。 骨骼的确切位置取决于父对象的位置和旋转。 树的顶部没有父级的骨骼称为根骨骼。 在初始化过程中,对根骨骼的处理略有不同。 根骨骼的属性角度定义了其在整个场景中的旋转。 您可以认为它的父骨骼水平指向右侧。 现在,我们可以定义虚拟对象的结构,如图3所示。可以在下面的代码示例中看到生成虚拟对象骨架的代码。

// Definition of head
final Bone head = new Bone(30, 90);// Definition of torso
final Bone torso = new Bone(80, 0);
head.getChildren().add(torso);final Bone[] upperArm = new Bone[2];
final Bone[] upperLeg = new Bone[2];for (int i=0; i<2; i++) {// Definition upper armsupperArm[i] = new Bone(60, 60 - 90 * i);// Definition of lower armsfinal Bone lowerArm = new Bone(60, -90);upperArm[i].getChildren().add(lowerArm);// Definition of upper legsupperLeg[i] = new Bone(60, 30 - 90*i);// Definition of lower legsfinal Bone lowerLeg = new Bone(75, 90);upperLeg[i].getChildren().add(lowerLeg);
}// Connect arms and legs to head and torso
head.getChildren().addAll(upperArm);
torso.getChildren().addAll(upperLeg);

查看Gist上的代码。

附加视觉组件

骨骼本身不可见。 它们只是定义结构。 属性内容Node对象的ObservableList ,可用于将可见元素附加到骨骼。

// Attaching visual elements to a bone
final Bone bone = new Bone(50, 30);
bone.getContent().addAll(
new Circle(20),
new Ellipse(45, 0, 25, 15),
new Circle(80, 0, 10)
);

查看Gist上的代码。

添加视觉元素

图4:添加视觉元素

附着的Node对象的位置和旋转由基础骨骼确定。 所有附加节点的局部坐标系的原点是骨骼的头部位置。 如果头部位置已移动,则其所有节点也将移动。 骨骼的旋转也传递到节点。 如果骨骼完全不旋转并且角度值为0,则它​​是水平指向右。 在上面的代码示例中,骨骼定义了两个圆和一个椭圆。 该骨骼如图4所示。下面的代码示例显示了所需的更改,这些更改通过附加圆和椭圆来定义虚拟对象的外观。 生成的虚拟对象可以在图5中看到。在图片中,我添加了骨骼的符号以使其可见。 请注意,视觉组件均不会旋转,并且所有位置都位于骨骼本地。 场景中的最终位置和旋转仅根据骨骼的位置和旋转来计算。

// Definition of head
final Bone head = new Bone(30, 90);
head.getContent().add(new Ellipse(20, 15));// Definition of torso
final Bone torso = new Bone(80, 0);
torso.getContent().add(new Ellipse(40, 0, 50, 20));
head.getChildren().add(torso);final Bone[] upperArm = new Bone[2];
final Bone[] upperLeg = new Bone[2];for (int i=0; i<2; i++) {// Definition upper armsupperArm[i] = new Bone(60, 60 - 90 * i);upperArm[i].getContent().add(new Ellipse(22.5, 0, 30, 12.5));// Definition of lower armsfinal Bone lowerArm = new Bone(60, -90);lowerArm.getContent().addAll(new Circle(12.5), new Ellipse(30, 0, 20, 12.5), new Circle(60, 0, 12.5));upperArm[i].getChildren().add(lowerArm);// Definition of upper legsupperLeg[i] = new Bone(60, 30 - 90*i);upperLeg[i].getContent().add(new Ellipse(20, 0, 30, 15));// Definition of lower legsfinal Bone lowerLeg = new Bone(75, 90);lowerLeg.getContent().addAll(new Circle(15), new Ellipse(40, 0, 30, 15), new Ellipse(75, -10, 10, 22.5));upperLeg[i].getChildren().add(lowerLeg);
}// Connect arms and legs to head and torso
head.getChildren().addAll(upperArm);
torso.getChildren().addAll(upperLeg);

查看Gist上的代码。

带有所有视觉元素的虚拟模型

图5:所有视觉元素都附有的假人

将所有内容添加到场景图中

现在只剩下最后一个片段,无法在屏幕上渲染虚拟对象: Skeleton类。 Skeleton类是Scenegraph和带有附加Node对象的骨骼之间的桥梁。 它扩展了Parent ,因此可以在Scenegraph中的任何位置添加。 可以像场景图中的任何其他节点一样对其进行平移,旋转,缩放和转换。

通过设置任何骨骼的属性骨架 ,可以链接骨架对象和动画对象的骨骼。 您会注意到,相同结构中所有骨骼的属性骨架随后将更新为指向相同的Skeleton对象。 同一结构中的两个骨骼不可能指向不同的骨骼对象。

要查看结果,请下载完整的Dummy.java文件。 要编译脚本,需要将库javafx-ik添加到类路径中。 您可以从GitHub下载源代码。

下一步是什么?

本教程的第一部分介绍了如何定义动画对象的静态结构(或骨架)以及如何附加可见的组件。 第二部分将说明如何对该结构进行动画处理以创建自然外观的动画。

参考:来自Mike博客博客的JCG合作伙伴 Michael Heinrichs的JavaFX Inverse Kinematics 2.0库 。

翻译自: https://www.javacodegeeks.com/2013/04/javafx-library-for-inverse-kinematics-2-0.html

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

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

相关文章

html权重值_史上最全的web前端面试题汇总及答案HtmlCss(二)

作者&#xff1a;樱桃小丸子儿链接&#xff1a;https://www.jianshu.com/p/abadcc84e2a4HTML&CSSimg的alt和title的异同&#xff1f;**alt **是图片加载失败时&#xff0c;显示在网页上的替代文字&#xff1b;**title **是鼠标放上面时显示的文字,title是对图片的描述与进一…

解决问题SyntaxError: Unexpected token import

ES6语法的模块导入导出(import/export)功能,我们在使用它的时候&#xff0c;可能会报错&#xff1a; SyntaxError: Unexpected token import 语法错误&#xff1a;此处不应该出现import 我遇到的情况是import语法不识别导致的。在这里&#xff0c;有两种方法可以解决。 1: 使用…

linux下添加用户并赋予root权限

1、添加用户&#xff0c;首先用adduser命令添加一个普通用户&#xff0c;命令如下&#xff1a; #adduser tommy //添加一个名为tommy的用户#passwd tommy //修改密码Changing password for user tommy.New UNIX password: //在这里输入新密码Retype new UNIX password: …

CSS定位机制

css定位机制和css动画变换 css定位机制 定位属性position&#xff08;相生相克&#xff09; 1 static&#xff1a;静态定位 2 relative&#xff1a;相对定位&#xff08;相对于自己原来的位置定位&#xff09; 3. absolute&#xff1a;绝对定位&#xff08;float&#xff09;…

使用Gradle的简单Spring MVC Web应用程序

除了我们现在将使用Spring MVC而不是原始servlet之外&#xff0c;该文章将与我们以前的文章Simple Gradle Web Application相似。 使用Gradle运行基本的Spring MVC应用程序确实很容易。 您可以在Github上下载本教程的源代码。 先决条件 安装Gradle 我们的基本项目结构将是&am…

tps波动很大的原因_花生价格小幅上涨,要突破6元大关?粮贩:还有很大距离...

花生是一种重要的油料作物&#xff0c;虽然并不是全国都种植&#xff0c;但在黄淮、长江流域&#xff0c;西北和东北等地区&#xff0c;均广泛种植&#xff0c;近期花生价格一直是农民朋友的关注点&#xff0c;从今年花生价格来看&#xff0c;自从花生上市后&#xff0c;价格起…

python—内置函数-字符串,eval,isinstance

eval() 功能&#xff1a;将字符串str当成有效的表达式来求值并返回计算结果。 语法&#xff1a; eval(source[, globals[, locals]]) -> value 参数&#xff1a; source&#xff1a;一个Python表达式或函数compile()返回的代码对象 globals&#xff1a;可选。必须是dictiona…

html css 基础(标签选择,分页,行和块元素)

&#xff08;1&#xff09;html标签选择 1、<a></a> 的功能有连接&#xff0c;下载&#xff0c;锚点 2、<span></span> 用来区分字体样式&#xff0c;<strong></strong>和<em></em>用来强调某段文字 3、如果是描述性的某段…

正确退出activity_如何退出Activity

如何退出Activity&#xff1f;如何安全退出已调用多个Activity的Application&#xff1f;对于单一Activity的应用来说&#xff0c;退出很简单&#xff0c;直接finish()即可。当然&#xff0c;也可以用killProcess()和System.exit()这样的方法。但是&#xff0c;对于多Activity的…

win主机ping不通linux的IP

1.虚拟机的中的linux系统设置成桥接模式 2.点击虚拟机的编辑选择虚拟网络编辑器 3.点击更改设置 4点击还原默认设置即可 转载于:https://www.cnblogs.com/yvanBk/p/9156972.html

使用LDAP保护Java EE6中的Web应用程序

在上一篇文章中&#xff0c;我们解释了如何在通过传输层安全性&#xff08;TLS&#xff09;/安全套接字层&#xff08;SSL&#xff09;传输数据时保护数据。 现在&#xff0c;让我们尝试了解如何为使用LDAP服务器进行身份验证的基于JEE 6的Web应用程序应用安全机制。 目的&…

围城---一段不错的观后感

世上有多少方鸿渐&#xff0c;年轻的时候骄傲自诩不凡&#xff0c;在最好的时段被大家包容吹捧&#xff0c;但迟早社会会揭开你的面具&#xff0c;发现下面的你软弱无能&#xff0c;假的文凭&#xff0c;一般的家世&#xff0c;不中用的傲气&#xff0c;你看不上爱耍小聪明的苏…

了解动态代理:Spring AOP基础

为什么选择AOP&#xff1a; 要了解AOP&#xff08;面向方面​​的编程&#xff09;&#xff0c;我们需要了解软件开发中的“横切关注点”。 在每个项目中&#xff0c;都有一定数量的代码在多个类&#xff0c;多个模块中重复执行&#xff0c;例如几乎所有类和所有模块都需要记录…

设计模式(二十二)------23种设计模式(14):解释器模式

使用频率&#xff1a;★☆☆☆☆ 一、什么是解释器模式 定义一些语法规则&#xff0c;然后定义一个解析器去解析该语法&#xff1b; 所谓解释器模式就是定义语言的文法&#xff0c;并且建立一个解释器来解释该语言中的句子。 在这里我们将语言理解成使用规定格式和语法的代码。…

7 win 卸载node_node怎么卸载?Windows卸载node方法

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境&#xff0c;很多开发的朋友都在电脑上安装了node&#xff0c;那么如何卸载呢&#xff1f;很多用户可能不是很清楚&#xff0c;并且要卸载干净无残留&#xff0c;下面一起来看看小编分享的方法吧。Node卸载步骤如下&am…

使用jclouds库在Amazon S3上上传

在Java世界中&#xff0c;有几种将内容上载到S3存储桶的好方法–在本文中&#xff0c;我们将研究jclouds库为此提供的功能。 要使用jclouds –特别是本文中讨论的API&#xff0c;应将这种简单的Maven依赖项添加到项目的pom中&#xff1a; <dependency><groupId>or…

【HTML】前端性能优化之CDN和WPO的比较

CDN通过将资源存储在更接近用户的位置&#xff0c;缩短到服务器的往返行程&#xff0c;加快页面加载时间来解决性能问题。WPO解决方案&#xff0c;如Radware的FastView&#xff0c;则在前端进行性能提升处理&#xff0c;使页面更有效地呈现在浏览器中。 “我已经使用了内容交付…

python自动化测试-D1-学习笔记之二

Jmeter 一、Jmeter连接数据库 1、打开Jmeter&#xff0c;在Jmeter—测试计划中添加mysql的jar包&#xff0c;见如下截图&#xff1a; 2、添加好jar包后&#xff0c;添加jdbc&#xff0c;并进行设置&#xff0c;如下图 3、添加JDBC Request&#xff0c;然后在JDBC Request中操作…

Android View 的滑动

一、View 的简介 View是所有可视化控件的基类&#xff0c;我们平时接触的所有的控件&#xff0c;比如说TextView,Button 等等都继承于View。View是Android 在视觉上的呈现&#xff0c;是界面层控件的一种抽象&#xff0c;可以是单个控件也可以是一组控件。 二、坐标系 1、Andro…

ActiveMQ消息优先级:工作原理

关于ActiveMQ的消息优先级支持 &#xff0c; 邮件列表上通常会不断出现一些问题&#xff0c;以及有关观察到的行为和“真正支持什么”的好问题&#xff1f; 我希望可以帮助您了解幕后情况以及可以支持的优先级。 详细信息可能会有些麻烦。 如果您对这些细节不感兴趣&#xff0c…