Kaynağa Gözat

fix: 改进了点位同步

xzw 2 yıl önce
ebeveyn
işleme
9084544981
2 değiştirilmiş dosya ile 84 ekleme ve 25 silme
  1. 2 2
      public/smart-kankan.html
  2. 82 23
      src/utils/ConvertViews.js

+ 2 - 2
public/smart-kankan.html

@@ -27,9 +27,9 @@
         <div id="app"></div>
         <script src="<%= BASE_URL %><%= VUE_APP_SDK_DIR %>kankan-sdk-deps.js?v=<%= VUE_APP_VERSION %>"></script>
         <script src="<%= BASE_URL %><%= VUE_APP_SDK_DIR %>kankan-sdk.js?v=<%= VUE_APP_VERSION %>"></script>
-        <!-- 
+        
         <script src="http://192.168.0.80:3099/dist/sdk/kankan-sdk-deps.js?v=<%= VUE_APP_VERSION %>"></script>
         <script src="http://192.168.0.80:3099/dist/sdk/kankan-sdk.js?v=<%= VUE_APP_VERSION %>"></script>
-        -->
+        
     </body>
 </html>

+ 82 - 23
src/utils/ConvertViews.js

@@ -463,7 +463,7 @@ export default class ConvertViews extends THREE.EventDispatcher{
         //获取两个场景的lon偏差值
         //需要点的个数>1, 且两个场景点一一对应,位置接近且顺序一致
 
-        let diffLonAve = 0, length,
+        let diffLonAve = 0, length, diffLon,
             diffLons = [] 
              
         let panoPos1 = sourceFakeApp.panos.map(e=>{
@@ -494,22 +494,34 @@ export default class ConvertViews extends THREE.EventDispatcher{
             let pos22 = new THREE.Vector3().copy(panoPos2[(index + 1) % length])
             let vec1 = new THREE.Vector3().subVectors(pos11, pos12).setY(0)
             let vec2 = new THREE.Vector3().subVectors(pos21, pos22).setY(0)
-            let diffLon = math.getAngle(vec1, vec2, 'z')
-            diffLons.push(diffLon)
-            diffLonAve += diffLon
+            let diffLon0 = math.getAngle(vec1, vec2, 'z')
+            diffLons.push(diffLon0)
+            diffLonAve += diffLon0
             index++
         }
 
         console.log('diffLons', diffLons)
         diffLonAve /= length
-        console.log('diffLonAve', diffLonAve)
         
-        let upVec = sourceFakeApp.sceneType == "laser" ? new THREE.Vector3(0, 0, 1) : new THREE.Vector3(0, 1, 0)  //左右两个场景类型一样。暂不会有laser和4dkankan同步的情况
-        let diffQua = new THREE.Quaternion().setFromAxisAngle(upVec, diffLonAve) 
         
+        diffLons = diffLons.sort((a,b)=>{return a-b})
+         
+        if(length<=2){
+            diffLon = diffLonAve
+        }else{ 
+            //只选中间的一部分(类似中位数),以去掉坏点
+            let i=1/3, j=2/3;  //起始和终止。选取中间的三分之一
+            let midList = diffLons.slice(i*length,Math.ceil(j*length)); 
+            let sum = midList.reduce((total,cur)=>{return total+cur},0); 
+            diffLon = sum / midList.length;
+        } 
+        
+        let upVec = sourceFakeApp.sceneType == "laser" ? new THREE.Vector3(0, 0, 1) : new THREE.Vector3(0, 1, 0)  //左右两个场景类型一样。暂不会有laser和4dkankan同步的情况
+        let diffQua = new THREE.Quaternion().setFromAxisAngle(upVec, diffLon) 
+        console.log('diffLonAve', diffLonAve, 'diffLon', diffLon)
         
         return {
-            diffLon : diffLonAve,
+            diffLon,   //diffLonAve,
             diffQua  ,
             diffQuaInvert : diffQua.clone().invert(),
             sourceFakeApp,
@@ -523,8 +535,8 @@ export default class ConvertViews extends THREE.EventDispatcher{
     computeShift(o={} ) { //获取两个可自由移动的场景的旋转和位移偏差值
         //需要点的个数>1, 且两个场景点一一对应,位置接近且顺序一致
         
-        let panoPos1, panoPos2, convertInfo = o.convertInfo || {}
-         
+        let panoPos1, panoPos2, convertInfo = o.convertInfo || {}, center1, center2,  matrix 
+        
         if(o.sourceApp && o.targetApp && o.sourceApp.sceneType == o.targetApp.sceneType){
             var angle = convertInfo.diffLon; //直接使用 更精准
             panoPos1 = o.sourceApp.fakeApp.panos.map(e=>{
@@ -532,7 +544,7 @@ export default class ConvertViews extends THREE.EventDispatcher{
             })
             panoPos2 = o.targetApp.fakeApp.panos.map(e=>{
                 return e.position
-            }) 
+            })  
             convertInfo.sourceFakeApp = o.sourceApp.fakeApp 
             convertInfo.targetFakeApp = o.targetApp.fakeApp 
         }else{
@@ -548,23 +560,58 @@ export default class ConvertViews extends THREE.EventDispatcher{
             var angle = math.getAngle(vec1, vec2, 'z')
         }
         
-        //var scale = vec2.length()/vec1.length() 
-        //var scaleMatrix = new THREE.Matrix4().makeScale(scale,scale,scale)   //默认为1, 但由于坐标暂时是自己采集的,所以结果会是第一个点附近比较正确,越远偏差越大
-        var matrix = new THREE.Matrix4().setPosition(panoPos1[0].clone().negate())//先以点0为基准平移到000
-        //matrix.premultiply(scaleMatrix)//再缩放
-        var rotateMatrix = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0,0,1), angle );
-        matrix.premultiply(rotateMatrix)//和旋转
-        var moveBackMatrix = new THREE.Matrix4().setPosition(panoPos2[0])
-        matrix.premultiply(moveBackMatrix)//再移动到realPosition的点0处
-            
+        let compute = (panoPos1,panoPos2)=>{
+            //中心点
+            center1 = panoPos1.reduce((t,c)=>{return t.add(c)},new THREE.Vector3())
+            center2 = panoPos2.reduce((t,c)=>{return t.add(c)},new THREE.Vector3())
+            center1.multiplyScalar(1/panoPos1.length)
+            center2.multiplyScalar(1/panoPos2.length) 
             
+            //var scale = vec2.length()/vec1.length() 
+            //var scaleMatrix = new THREE.Matrix4().makeScale(scale,scale,scale)   //默认为1, 但由于坐标暂时是自己采集的,所以结果会是第一个点附近比较正确,越远偏差越大
+            var matrix = new THREE.Matrix4().setPosition(/* panoPos1[0] */center1.clone().negate())//先以点0为基准平移到000
+            //matrix.premultiply(scaleMatrix)//再缩放
+            var rotateMatrix = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0,0,1), angle );
+            matrix.premultiply(rotateMatrix)//和旋转
+            var moveBackMatrix = new THREE.Matrix4().setPosition(/* panoPos2[0] */center2)
+            matrix.premultiply(moveBackMatrix)//再移动到realPosition的点0处
+            return matrix
+        }
+         
+        matrix = compute(panoPos1,panoPos2)
+         
             
+        //检查是否重合。直接将matrix作用于pos1中,理想情况是会和pos2完全一样。   
+        let diffVecs = panoPos1.map((e,i)=>{
+            let newPos = e.clone().applyMatrix4(matrix) //旋转过后。
+            return new THREE.Vector3().subVectors(newPos, panoPos2[i]) // 和pos1之间的偏差。越小越重合
+        })   
+        let disDiffs = diffVecs.map(e=>e.length())
+        let disDiffs2 = disDiffs.sort((a,b)=>{return a-b})
+        let maxTolerance = 2 * disDiffs2[Math.round(diffVecs.length/3)]  //最大值限制在1/3的两倍处。不用绝对数值的原因:主要考虑到万一拍摄间隔很大,那么最小的diff都可能很大,所以还是按比例划分吧。    
+        if(disDiffs2[1]>=maxTolerance){//至少有两个 
+            maxTolerance = disDiffs2[1]
+        }
+        console.log('difVecs',diffVecs, 'disDiffs2',disDiffs2,'maxTolerance',maxTolerance)   
+        
+        
+        //排除掉偏差大的坏点
+        let panoPos1new = panoPos1.filter((p,i)=>{return disDiffs[i]<=maxTolerance})    
+        let panoPos2new = panoPos2.filter((p,i)=>{return disDiffs[i]<=maxTolerance})    
+          
+        //用剩下的点再算一次    
+        matrix = compute(panoPos1new,panoPos2new)
+        
+        
+        
         convertInfo.convertMatrix = matrix
         convertInfo.convertMatrixInvert = matrix.clone().invert()
         return convertInfo
         //return { convertMatrix:  matrix, convertMatrixInvert:matrix.clone().invert(), convertAxis:o.convertAxis}
-          
-
+        /* 
+            用于场景自由移动时。缺点:切换点云模式时,如果点位不准 偏差大,就会瞬移一下。
+            不过目前四维看看不支持到dollhouse
+        */
     }
     
 
@@ -1025,12 +1072,24 @@ function getId(){
 note:
 
 
-访问:window[0].fakeApp, window[1].fakeApp
+访问:
+window[0]   window[1]
+window[0].fakeApp, window[1].fakeApp
 
 旋转只能通过target设置, 不能直接改camera.quaternion
 当且仅当发送方相机属性变化后才传递过来,就不在这里判断是否变化了。
 (所以只需要实时检测相机是否改变, hasChanged后发送)
 
+
+如果角度同步有偏差,请查看
+computeAveDiffLon
+如果位置同步有偏差,请查看
+computeShift,
+添加label:
+window[1].viewer.images360.panos.forEach(e=>e.addLabel())
+
+
+
  */
  
  /*