2012-09-19 19 views
6

मैं जावास्क्रिप्ट/jquery (डीओएम आधारित, कैनवास नहीं) में किसी प्रकार का ड्रैग और ड्रॉप ऐप बना रहा हूं।माउस निर्देशांक को 3 डी प्लान में अनुवाद करें

विचार 3 डी दृश्य (3 डी में घूर्णन वाला div) पर divs खींचने में सक्षम होना है।

यह एक 2 डी योजना पर काम करता है, समस्या यह है जब मैं 3 डी में दृश्य घुमाने के लिए, वस्तुओं स्थिति वास्तविक माउस स्थिति को प्रतिबिंबित नहीं करता है, लेकिन निर्देशांक 3 डी

में अनुवाद इलस्ट्रेटेड उदाहरण: exemple

EXEMPLE ON JSFIDDLE

मैं वस्तुओं को माउस की पूर्ण स्थिति के सापेक्ष आगे बढ़ाना चाहता हूं।

मैं इस तरह माउस स्थिति की गणना:

document.addEventListener(gestureMove, function (event) { 
    if (mouseDown == true) { 
    event.preventDefault(); 
    moveX = (event.pageX - $('#scene').offset().left); 
    moveY = (event.pageY - $('#scene').offset().top); 
} 

#scene { 
    width: 1000px; 
    height: 1000px; 
    -webkit-transform-style: preserve-3d; 
    -webkit-transform: rotateX(35deg); 
} 

एक प्रारंभिक समाधान माउस की स्थिति और वस्तु प्रारंभिक स्थिति के आधार पर के बीच अंतर की गणना करने के लिए था, और खींचें के दौरान वस्तु स्थिति में जोड़ने । यह काम कर रहा था, लेकिन एनीमेशन वास्तव में चंचल था और बिल्कुल चिकनी नहीं था।

मुझे यकीन है कि 3 डी प्लान के सापेक्ष माउस निर्देशांक प्राप्त करने का एक और आसान तरीका है, लेकिन इस बिंदु पर वास्तविक समाधान नहीं मिला।

इस विषय पर अधिकांश खोज परिणाम गेमिंग उन्मुख भाषाओं, या कैनवास/वेबलॉग प्रश्नों को इंगित करते हैं।

कोई विचार?

धन्यवाद

+0

मुझे लगता है कि Google स्केच-अप ने इसका अच्छा काम किया है। –

+0

आप शायद परिप्रेक्ष्य प्रक्षेपण के विपरीत कर रहे हैं: http://en.wikipedia.org/wiki/3D_projection#Perspective_projection – Blender

+0

क्या आप अपने कोड को jsfiddle में फिट करने के लिए पर्याप्त नीचे डिस्टिल कर सकते हैं? – Shmiddty

उत्तर

2

मान लिया जाये कि एक पूर्ण स्क्रीन स्थिति है कि अपने माउस की स्थिति, और आप हड़पने और एक 3 डी विमान माउस स्थिति पर सीधे आधारित पर चारों ओर एक वस्तु स्लाइड करने के लिए करना चाहते हैं:

आप अपने 3 डी का प्रतिनिधित्व कर सकते लक्ष्य विमान के रूप में:

  • एक 3 डी मूल बिंदु O
  • दो 3 डी वैक्टर U और V, दिशा का प्रतिनिधित्व यू और वी कुल्हाड़ियों की

फिर, किसी दिए गए 3 डी बिंदु विमान के लिए इसी निर्देशांक [u,v] है:

point3d P = O + u*U + v*V 

उसके बाद, आप कार्य है कि स्क्रीन पर इस विशेष 3 डी बिंदु के नक्शे को जोड़ सकते हैं ; यह आमतौर पर 3 डी रूपांतरण matrices ModelMatrix, ViewMatrix, और ProjectionMatrix, और 2 डी स्क्रीन मूल बिंदु origin_2d और एक 2 डी स्केलिंग वेक्टर scale_2d द्वारा निर्धारित व्यूपोर्ट परिवर्तन के साथ वर्णित है। एक आसानी से अचूक तरीके से समस्या को हल करने के लिए, .w जोड़कर, उनमें से प्रत्येक को समन्वयित करके, समरूप समन्वय में सब कुछ बढ़ावा दें।इस अतिरिक्त एक स्केलिंग कारक के रूप में कार्य का समन्वय - कार्तीय निर्देशांक वापस पाने के लिए, आप .w मूल्य द्वारा सजातीय .x और .y मूल्यों विभाजित करने की आवश्यकता:

P_hom = [u, v, 1] * [U.x, U.y, U.z, 0] = [u, v, 1] * TexMatrix 
        [V.x, V.y, V.z, 0] 
        [O.x, O.y, O.z, 1] 

P_clip_hom = P_hom * ModelMatrix * ViewMatrix * ProjectionMatrix 
      = P_hom * ModelViewProjectionMatrix 

screenpos_hom = P_clip_hom * [scale_2d.x  0  0] = P_clip_hom * PortMatrix 
          [ 0  scale_2d.y 0] 
          [ 0   0  0] 
          [origin_2d.x origin_2d.y 1] 

So, screenpos_hom = [u, v, 1] * TexMatrix * ModelViewProjectionMatrix * PortMatrix 
        = [u, v, 1] * TexToScreenMatrix 

-> [screenpos.x, screenpos.y] = [screenpos_hom.x, screenpos_hom.y]/screenpos_hom.w 

ध्यान दें कि TexToScreenMatrix एक 3x3 मैट्रिक्स है; आप इसे उलटने के लिए सक्षम होना चाहिए:

UV_2d_hom = [screenpos.x, screenpos.y, 1] * (TexToScreenMatrix)^-1 

-> [u, v] = [UV_2d_hom.x, UV_2d_hom.y]/UV_2d_hom.w 

अंत में, आप उपयोग कर सकते हैं [u,v] निर्देशांक सीधे, या यदि आपने उपरोक्त वर्णन 3 डी बिंदु P पुन: बनाने के लिए उनका उपयोग कर सकते हैं।

+0

धन्यवाद! लेकिन मुझे यह सुनिश्चित नहीं है कि जावास्क्रिप्ट में 3 डी रूपांतरण मैट्रिक्स का उपयोग कैसे करें। इसके अलावा, मेरे उदाहरण में "डब्ल्यू" क्या है? – Julian

+0

मुझे डर है कि मुझे नहीं पता कि ये जावास्क्रिप्ट/वेबकिट मंच पर कैसे बाध्य हैं। यदि आप सीधे वेबकिट रूपांतरण मैट्रिक्स पर नहीं पहुंच पा रहे हैं, तो आपको जावास्क्रिप्ट में 3 डी गणित से मिलान करना पड़ सकता है - उदाहरण के लिए, यदि आप 'rotateX (35deg)' का उपयोग करते हैं, तो दुर्भाग्यवश आपको अपना 3 डी एक्स-रोटेशन सेट अप करने की आवश्यकता होगी 35 डिग्री के लिए मैट्रिक्स और इसे अपने 'व्यूमैट्रिक्स' में गुणा करें ... – comingstorm

+0

"डब्ल्यू" के लिए, मैंने इसे अपने उत्तर में संक्षेप में समझाया; "डब्ल्यू" द्वारा विभाजन आपको पहले स्थान पर 3 डी परिप्रेक्ष्य करने देता है। यदि आप इसे बेहतर समझना चाहते हैं, तो आपको मूल 3 डी गणित पर एक लंबी और बेहतर प्रस्तुति की आवश्यकता है; [3 डी प्रक्षेपण] (http://en.wikipedia.org/wiki/3D_projection) पर विकिपीडिया का प्रयास करें। – comingstorm

संबंधित मुद्दे