主要思想是采用投票箱机制,把物体移动的方向从360归一到8个方向:

用到的主要代码如下:

以相机为坐标原点,把移动的小码变换到大码坐标下:

坐标变换

Matrix4x4 extinsic_obj1 = image1.transform.localToWorldMatrix;//image1 相对于camera的 transform metric
Matrix4x4 extinsic_obj2 = imageTarget.transform.localToWorldMatrix;//imageTarget 相对于camera的 transform metric
Matrix4x4 relat = extinsic_obj2.inverse * extinsic_obj1  ;//Vector4 controlPoint = new Vector4 (image1.transform.position.x, image1.transform.position.y, image1.transform.position.z, 1.0f);
Vector4 controlPoint = new Vector4 (0,0, 0, 1.0f);
Vector4 new_controlPoint = relat * controlPoint;

如果坐标原点在大码上,则不需要变换了。(当然也没错,但没有必要了)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System;
using System.Threading;
using System.IO.Ports;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;public class Guidance: MonoBehaviour {public GameObject imageTarget;//public GameObject arrow;public GameObject image1;public GameObject cyl;public GameObject startpoint;public GameObject thispoint;GameObject arrow1;GameObject arrow2;GameObject arrow3;GameObject arrow4;GameObject arrow5;GameObject arrow6;GameObject arrow7;GameObject arrow8;GameObject point1;GameObject point2;GameObject point3;GameObject point4;GameObject point5;public List<GameObject> pointList;public int signal=0;public int i;public int feedback;int n=0;public bool start=false;public float x0=0.0f;float y0=0.0f;public float z0=0.0f;public float x1=0.0f;public float z1=-0.1f;public float d=0.0f;public float alpha;public float beta;public float theta;// Use this for initializationvoid Start () {pointList=new List<GameObject>();GameObject point1=GameObject.Find("point0");point1.SetActive (false);GameObject point2=GameObject.Find("point1");point2.SetActive (false);GameObject point3=GameObject.Find("point2");point3.SetActive (false);GameObject point4=GameObject.Find("point3");point4.SetActive (false);GameObject point5=GameObject.Find("point4");point5.SetActive (false);pointList.Add(point1);pointList.Add(point2);pointList.Add(point3);pointList.Add(point4);pointList.Add(point5);arrow1=GameObject.Find("arrow1");arrow1.SetActive (false);arrow2=GameObject.Find("arrow2");arrow2.SetActive (false);arrow3=GameObject.Find("arrow3");arrow3.SetActive (false);arrow4=GameObject.Find("arrow4");arrow4.SetActive (false);arrow5=GameObject.Find("arrow5");arrow5.SetActive (false);arrow6=GameObject.Find("arrow6");arrow6.SetActive (false);arrow7=GameObject.Find("arrow7");arrow7.SetActive (false);arrow8=GameObject.Find("arrow8");arrow8.SetActive (false);i = 0;feedback = 1;thispoint = pointList[0];//arrow.SetActive (false);}// Update is called once per framevoid Update () {if (start) {Matrix4x4 extinsic_obj1 = image1.transform.localToWorldMatrix;//image1 相对于camera的 transform metric Matrix4x4 extinsic_obj2 = imageTarget.transform.localToWorldMatrix;//imageTarget 相对于camera的 transform metricMatrix4x4 relat = extinsic_obj2.inverse * extinsic_obj1  ;//Vector4 controlPoint = new Vector4 (image1.transform.position.x, image1.transform.position.y, image1.transform.position.z, 1.0f);Vector4 controlPoint = new Vector4 (0,0, 0, 1.0f);Vector4 new_controlPoint = relat * controlPoint;//            //相对于小码的局部坐标
//          thispoint.transform.localPosition = new Vector3(new_controlPoint.x , new_controlPoint.y , new_controlPoint.z );//image 相对于 imageTarget 的 local positionx0 = new_controlPoint.x;y0 = new_controlPoint.y;z0 = new_controlPoint.z;//imageTarget 上的点 相对于 imageTarget 的 local positionx1 = thispoint.transform.localPosition.x;z1 = thispoint.transform.localPosition.z;
//          x1 = thispoint.transform.position.x;
//          z1 = thispoint.transform.position.z;d = Mathf.Sqrt ((x1 - x0) * (x1 - x0) + (z1 - z0) * (z1 - z0));//alpha=image1.transform.rotation.eulerAngles.y;alpha = image1.transform.localEulerAngles.y;//      if (alpha > 360)//           alpha = alpha - 360;if (alpha > 180)alpha = alpha - 360;beta = Mathf.Atan2 ((z1 - z0), (x1 - x0)) * 180 / Mathf.PI;theta = alpha + beta;//haptic feedbackif (feedback == 0) {//arrow.SetActive (false);arrow1.SetActive (false);arrow2.SetActive (false);arrow3.SetActive (false);arrow4.SetActive (false);arrow5.SetActive (false);arrow6.SetActive (false);arrow7.SetActive (false);arrow8.SetActive (false);if (d > 0.02) {if (theta >= -22.5 && theta < 22.5) {signal = 1;}if (theta >= 22.5 && theta < 67.5) {signal = 8;}if (theta >= 67.5 && theta < 112.5) {signal = 7;}if (theta >= 112.5 && theta < 157.5) {signal = 6;}if (theta >= 157.5 && theta <= 180 || theta >= -180 && theta < -157.5) {signal = 5;}if (theta >= -157.5 && theta < -112.5) {signal = 4;} if (theta >= -112.5 && theta < -67.5) {signal = 3;} if (theta >= -67.5 && theta < -22.5) {signal = 2;} } else {signal = 0;
//                  WriteData ("0");if (i == 4) {start = false;}n = 1;}if (n == 1 && d > 0.02) {i++;if (i >= 5)i = 0;thispoint = pointList [i];n = 0;}}//visual feedbackif (feedback == 1) {//arrow.SetActive (true);//arrow.transform.localPosition = new Vector3(x0,y0,z0);if (d > 0.02) {if (theta >= -22.5 && theta < 22.5) {arrow1.SetActive (true);arrow2.SetActive (false);arrow3.SetActive (false);arrow4.SetActive (false);arrow5.SetActive (false);arrow6.SetActive (false);arrow7.SetActive (false);arrow8.SetActive (false);//                     arrow.transform.localRotation = Quaternion.Euler (0, -90, 0);}if (theta >= 22.5 && theta < 67.5) {arrow1.SetActive (false);arrow2.SetActive (false);arrow3.SetActive (false);arrow4.SetActive (false);arrow5.SetActive (false);arrow6.SetActive (false);arrow7.SetActive (false);arrow8.SetActive (true);//                     arrow.transform.localRotation = Quaternion.Euler (0, -135, 0);}if (theta >= 67.5 && theta < 112.5) {arrow1.SetActive (false);arrow2.SetActive (false);arrow3.SetActive (false);arrow4.SetActive (false);arrow5.SetActive (false);arrow6.SetActive (false);arrow7.SetActive (true);arrow8.SetActive (false);//                       arrow.transform.localRotation = Quaternion.Euler (0, -180, 0);}if (theta >= 112.5 && theta < 157.5) {arrow1.SetActive (false);arrow2.SetActive (false);arrow3.SetActive (false);arrow4.SetActive (false);arrow5.SetActive (false);arrow6.SetActive (true);arrow7.SetActive (false);arrow8.SetActive (false);//                      arrow.transform.localRotation = Quaternion.Euler (0, 135, 0);}if (theta >= 157.5 && theta <= 180 || theta >= -180 && theta < -157.5) {arrow1.SetActive (false);arrow2.SetActive (false);arrow3.SetActive (false);arrow4.SetActive (false);arrow5.SetActive (true);arrow6.SetActive (false);arrow7.SetActive (false);arrow8.SetActive (false);//                     arrow.transform.localRotation = Quaternion.Euler (0, 90, 0);}if (theta >= -157.5 && theta < -112.5) {arrow1.SetActive (false);arrow2.SetActive (false);arrow3.SetActive (false);arrow4.SetActive (true);arrow5.SetActive (false);arrow6.SetActive (false);arrow7.SetActive (false);arrow8.SetActive (false);//                      arrow.transform.localRotation = Quaternion.Euler (0, 45, 0);} if (theta >= -112.5 && theta < -67.5) {arrow1.SetActive (false);arrow2.SetActive (false);arrow3.SetActive (true);arrow4.SetActive (false);arrow5.SetActive (false);arrow6.SetActive (false);arrow7.SetActive (false);arrow8.SetActive (false);//                      arrow.transform.localRotation = Quaternion.Euler (0, 0, 0);} if (theta >= -67.5 && theta < -22.5) {arrow1.SetActive (false);arrow2.SetActive (true);arrow3.SetActive (false);arrow4.SetActive (false);arrow5.SetActive (false);arrow6.SetActive (false);arrow7.SetActive (false);arrow8.SetActive (false);//                        arrow.transform.localRotation = Quaternion.Euler (0, -45, 0);}
//                  if (theta >= -22.5 && theta < 22.5) {
//                      arrow.transform.localRotation = Quaternion.Euler (0, -90, 0);
//                  }
//                  if (theta >= 22.5 && theta < 67.5) {
//                      arrow.transform.localRotation = Quaternion.Euler (0, -135, 0);
//                  }
//                  if (theta >= 67.5 && theta < 112.5) {
//                      arrow.transform.localRotation = Quaternion.Euler (0, -180, 0);
//                  }
//                  if (theta >= 112.5 && theta < 157.5) {
//                      arrow.transform.localRotation = Quaternion.Euler (0, 135, 0);
//                  }
//                  if (theta >= 157.5 && theta <= 180 || theta >= -180 && theta < -157.5) {
//                      arrow.transform.localRotation = Quaternion.Euler (0, 90, 0);
//                  }
//                  if (theta >= -157.5 && theta < -112.5) {
//                      arrow.transform.localRotation = Quaternion.Euler (0, 45, 0);
//                  }
//                  if (theta >= -112.5 && theta < -67.5) {
//                      arrow.transform.localRotation = Quaternion.Euler (0, 0, 0);
//                  }
//                  if (theta >= -67.5 && theta < -22.5) {
//                      arrow.transform.localRotation = Quaternion.Euler (0, -45, 0);
//                  } } else {cyl.GetComponent<MeshRenderer> ().material.color = Color.green;//pointList [i].SetActive (true);//arrow.SetActive (false);arrow1.SetActive (false);arrow2.SetActive (false);arrow3.SetActive (false);arrow4.SetActive (false);arrow5.SetActive (false);arrow6.SetActive (false);arrow7.SetActive (false);arrow8.SetActive (false);if (i == 4) {start = false;} n = 1;}if (n == 1 && d > 0.02) {//arrow.SetActive (true);cyl.GetComponent<MeshRenderer> ().material.color = Color.red;//pointList [i].SetActive (false);i++;if (i >= 5)i = 0;thispoint = pointList [i];n = 0;}}//visual+haptic feedbackif (feedback == 2) {//arrow.SetActive (true);//arrow.transform.localPosition = new Vector3(x0,y0,z0);if (d > 0.02) {//arrow.transform.localRotation = Quaternion.Euler (0,-beta,90);//if (theta >= -22.5 && theta < 22.5) {signal = 1;//WriteData ("1");arrow1.SetActive (true);arrow2.SetActive (false);arrow3.SetActive (false);arrow4.SetActive (false);arrow5.SetActive (false);arrow6.SetActive (false);arrow7.SetActive (false);arrow8.SetActive (false);//arrow.transform.localRotation = Quaternion.Euler (0, 0, 90);//arrow.transform.localRotation = Quaternion.Euler (0, -90, 0);//Debug.Log ("1");}if (theta >= 22.5 && theta < 67.5) {signal = 8;//WriteData ("8");arrow1.SetActive (false);arrow2.SetActive (false);arrow3.SetActive (false);arrow4.SetActive (false);arrow5.SetActive (false);arrow6.SetActive (false);arrow7.SetActive (false);arrow8.SetActive (true);//arrow.transform.localRotation = Quaternion.Euler (0, -45, 90);//arrow.transform.localRotation = Quaternion.Euler (0, -135, 0);//Debug.Log ("8");}if (theta >= 67.5 && theta < 112.5) {signal = 7;//WriteData ("7");arrow1.SetActive (false);arrow2.SetActive (false);arrow3.SetActive (false);arrow4.SetActive (false);arrow5.SetActive (false);arrow6.SetActive (false);arrow7.SetActive (true);arrow8.SetActive (false);//                     arrow.transform.localRotation = Quaternion.Euler (0, -90, 90);//arrow.transform.localRotation = Quaternion.Euler (0, -180, 0);//Debug.Log ("7");}if (theta >= 112.5 && theta < 157.5) {signal = 6;//WriteData ("6");arrow1.SetActive (false);arrow2.SetActive (false);arrow3.SetActive (false);arrow4.SetActive (false);arrow5.SetActive (false);arrow6.SetActive (true);arrow7.SetActive (false);arrow8.SetActive (false);//                     arrow.transform.localRotation = Quaternion.Euler (0, -135, 90);//arrow.transform.localRotation = Quaternion.Euler (0, 135, 0);//Debug.Log ("6");}if (theta >= 157.5 && theta <= 180 || theta >= -180 && theta < -157.5) {signal = 5;//WriteData ("5");arrow1.SetActive (false);arrow2.SetActive (false);arrow3.SetActive (false);arrow4.SetActive (false);arrow5.SetActive (true);arrow6.SetActive (false);arrow7.SetActive (false);arrow8.SetActive (false);//                       arrow.transform.localRotation = Quaternion.Euler (0, -180, 90);//arrow.transform.localRotation = Quaternion.Euler (0, 90, 0);//Debug.Log ("5");}if (theta >= -157.5 && theta < -112.5) {signal = 4;//WriteData ("4");arrow1.SetActive (false);arrow2.SetActive (false);arrow3.SetActive (false);arrow4.SetActive (true);arrow5.SetActive (false);arrow6.SetActive (false);arrow7.SetActive (false);arrow8.SetActive (false);//                        arrow.transform.localRotation = Quaternion.Euler (0, 135, 90);//arrow.transform.localRotation = Quaternion.Euler (0, 45, 0);//Debug.Log ("4");} if (theta >= -112.5 && theta < -67.5) {signal = 3;//WriteData ("3");arrow1.SetActive (false);arrow2.SetActive (false);arrow3.SetActive (true);arrow4.SetActive (false);arrow5.SetActive (false);arrow6.SetActive (false);arrow7.SetActive (false);arrow8.SetActive (false);//                     arrow.transform.localRotation = Quaternion.Euler (0, 90, 90);//arrow.transform.localRotation = Quaternion.Euler (0, 0, 0);//Debug.Log ("3");} if (theta >= -67.5 && theta < -22.5) {signal = 2;//WriteData ("2");arrow1.SetActive (false);arrow1.SetActive (false);arrow2.SetActive (true);arrow3.SetActive (false);arrow4.SetActive (false);arrow5.SetActive (false);arrow6.SetActive (false);arrow7.SetActive (false);arrow8.SetActive (false);//                       arrow.transform.localRotation = Quaternion.Euler (0, 45, 90);//arrow.transform.localRotation = Quaternion.Euler (0, -45, 0);//Debug.Log ("2");} } else {signal = 0;
//                  WriteData ("0");cyl.GetComponent<MeshRenderer> ().material.color = Color.green;
//                  pointList [i].SetActive (true);//arrow.SetActive (false);arrow1.SetActive (false);arrow2.SetActive (false);arrow3.SetActive (false);arrow4.SetActive (false);arrow5.SetActive (false);arrow6.SetActive (false);arrow7.SetActive (false);arrow8.SetActive (false);if (i == 4) {start = false;}n = 1;}if (n == 1 && d > 0.02) {//arrow.SetActive (true);cyl.GetComponent<MeshRenderer> ().material.color = Color.red;
//                  pointList [i].SetActive (false);i++;if (i >= 5)i = 0;thispoint = pointList [i];n = 0;}}}}public void OnButtonClick_haptic (){feedback = 0;}public void OnButtonClick_visual (){feedback = 1;}public void OnButtonClick_vishaptic (){feedback = 2;}public void OnButtonClick_route1(){setPath (1);}public void OnButtonClick_route2(){setPath (2);}public void OnButtonClick_route3(){setPath (3);}public void OnButtonClick_start(){start = true;}public void OnButtonClick_end(){start = false;arrow1.SetActive (false);arrow2.SetActive (false);arrow3.SetActive (false);arrow4.SetActive (false);arrow5.SetActive (false);arrow6.SetActive (false);arrow7.SetActive (false);arrow8.SetActive (false);i = 0;thispoint = pointList [0];n = 0;}public void OnButtonClick_display(){pointList[0].SetActive (true);pointList[1].SetActive (true);pointList[2].SetActive (true);pointList[3].SetActive (true);pointList[4].SetActive (true);}public void OnButtonClick_nodisplay(){pointList[0].SetActive (false);pointList[1].SetActive (false);pointList[2].SetActive (false);pointList[3].SetActive (false);pointList[4].SetActive (false);}public void setPath(int path){if (path == 1) {startpoint.transform.localPosition=new Vector3(-0.4f,0,-0.4f);pointList[0].transform.localPosition = new Vector3 (-0.2f,0,0);pointList[1].transform.localPosition = new Vector3 (-0.4f,0,0.4f);pointList[2].transform.localPosition = new Vector3 (0,0,0.2f);pointList[3].transform.localPosition = new Vector3 (0.2f,0,-0.2f);pointList[4].transform.localPosition = new Vector3 (0.4f,0,0.2f);}if (path == 2) {startpoint.transform.localPosition=new Vector3(0.4f,0,-0.4f);pointList[0].transform.localPosition = new Vector3 (0,0,-0.2f);pointList[1].transform.localPosition = new Vector3 (-0.4f,0,-0.4f);pointList[2].transform.localPosition = new Vector3 (-0.2f,0,0);pointList[3].transform.localPosition = new Vector3 (0.2f,0,0.2f);pointList[4].transform.localPosition = new Vector3 (0,-0.2f,0.4f);}if (path == 3) {startpoint.transform.localPosition=new Vector3(0.4f,0,0.4f);pointList[0].transform.localPosition = new Vector3 (0.2f,0,0);pointList[1].transform.localPosition = new Vector3 (0.4f,0,-0.4f);pointList[2].transform.localPosition = new Vector3 (0,0,-0.2f);pointList[3].transform.localPosition = new Vector3 (-0.2f,0,0.2f);pointList[4].transform.localPosition = new Vector3 (-0.4f,0,-0.2f);}}}

unity Vuforia物体移动的方向用AR箭头表示出来相关推荐

  1. Unity | Vuforia物体识别

    一.准备工作:(我用的是Unity2018.2.15) 1. Unity3D:如果在Unity场景中层次面板下创建不了Vuforia的相关物体(如图1),那么需要安装Unity资源包下的Vuforia ...

  2. Unity Vuforia 之 AR 识别物体抖动的简单解决思路参考

    Unity Vuforia 之 AR 识别物体抖动的简单解决思路参考 目录 ​ 一.简单介绍 二.问题 三.简单解决思路 附录:Vuforia SDK 的功能如下 一.简单介绍 目前世界上主流的AR ...

  3. Unity Vuforia(高通)AR

    Unity Vuforia制作AR软件 使用过高通AR.百度AR.EasyAR,还是觉得高通的使用起来更加简易.今天就记录一下怎么使用Vuforia制作一个可识别2D图片与3D物体的AR软件. 使用步 ...

  4. 0基础小白用unity+vuforia实现AR随机抽卡/盲盒功能

    unity+Vuforia实现海洋动物随机AR盲盒 目录 Vuforia 一.在vuforia上注册许可证 二.添加识别目标图像数据 三.搭建AR程序 四.随机盲盒的进阶AR程序 Vuforia 这是 ...

  5. Unity Vuforia 之 简单实现Vuforia调用Android设备外接摄像头camera实现AR

    Unity Vuforia 之 简单实现Vuforia调用Android设备外接摄像头camera实现AR 目录 Unity Vuforia 之 简单实现Vuforia调用Android设备外接摄像头 ...

  6. Unity Vuforia(高通)AR全流程

    Unity Vuforia播放视频全过程(从Unity的安装到打包) 一.安装Unity (1)点击安装地址下载Unity Hub 下载好之后点击安装. (2)从Unity Hub进去安装Unity( ...

  7. unity AR3D物体识别

    上篇讲到了各种AR插件的一些对比 因为上个项目需求用到3D物体追踪.所以使用了EasyAR和Vuforia两种进行了测试对比. 因为如果需要AR识别,都需要有识别点,大致都是基于物体材质纹理来进行识别 ...

  8. Unity 控制物体移动的一些方法

    Unity 控制物体移动的一些方法 开坑, 回头慢慢补. 移动方法的总结. 1, 直接+=Vector3 transform.position += Vector3.forward * moveSpe ...

  9. Unity判断物体相对位置

    目录 一:点乘(Dot).叉乘(Cross) 1:点乘(Dot) 2:叉乘(Cross) 二:利用这个计算方位 1:点乘(Dot) 2:叉乘(Cross) 一:点乘(Dot).叉乘(Cross) 1: ...

  10. unity 陀螺仪 物体旋转和移动效果

    unity 陀螺仪 物体旋转和移动效果 直接上码 带注释 public class SDKGyroController : MonoBehaviour {//陀螺仪是否存在class GyroGame ...

最新文章

  1. 这 6 个 SpringBoot 项目够经典!
  2. webview重新加载(reload)或者发起 redirect request导致js和objc代码之间的bridge失联解决方案(亲测有效)...
  3. BLE蓝牙核心数据库结构解析
  4. python微信接口发送消息_Python 微信公众号发送消息
  5. eventbus使用_Android EventBus框架的使用介绍
  6. Telegram 支持删除聊天双方设备中的消息记录
  7. 在jupyter上绘制caffe网络迭代时的损失和精度曲线
  8. 数据库系统概论重点总结
  9. 数字电子技术之逻辑函数的化简及表示
  10. 局域网传输文件_局域网微信?这是什么神仙玩法
  11. Detours内联HOOK
  12. AI人工智能知识图谱Neo4j关联查询人物关系cypher查询
  13. 《机器学习实战》机器学习概述
  14. SSM毕设项目校园设备巡检管理系统04b46(java+VUE+Mybatis+Maven+Mysql)
  15. findIndex()
  16. 家用计算机做raid 2018,让电脑速度翻倍的方法,手把手教你组建RAID!
  17. 自动换刀主轴与手动换刀主轴优缺点对比
  18. Enigma机密码加密解密的实现
  19. 关于Selenium3在MicrosoftEdge浏览器中出现的问题
  20. 计算机基础(笔记)——计算机网络(链路层)

热门文章

  1. 网络断网远程计算机会自动修复么,网络断网不怕,教你自己动手修复_电脑故障...
  2. python subprocess 非阻塞_python中subprocess.PIPE上的非阻塞读取
  3. 虚拟机 Ubuntu安装gcc和g++
  4. linux看网络信息失败的原因,Linux版本登录提示网络错误
  5. vue表单中批量导入功能_Vue 编辑 新建表单复用的一些思考
  6. python创建子窗口_python GUI编程(Tkinter) 创建子窗口及在窗口上用图片绘图实例
  7. 线程同步机制的区别与比较及进程通信方法
  8. 手机 物理分辨率 逻辑分辨率
  9. 11.05 选择前n个记录
  10. 基于日志处理的ElasticSearch的学(gen)习(feng)