2012-07-16 36 views
7

को देखते हुए किया जा रहा है 4 अंकतब्दील इकाई वर्ग

QPolygon poly = transform.mapToPolygon(QRectF(0, 0, 1, 1)); 

का नतीजा हो कि कैसे मैं QTransform transform पा सकते हैं परिभाषित करने QTransform दिया 4 अंक बनाएँ? (बेहतर भी: यह भी एक मनमाना स्रोत आयत दिया)

प्रेरणा: एक छवि के को देखते हुए चार कोने अंक एक perspectively विकृत समन्वय प्रणाली में तैयार हो, मैं QPainter का उपयोग कर छवि कैसे आकर्षित कर सकते हैं?

Illustration of the problem

यह एक स्क्रीनशॉट जहां एक के आसपास परत के 4 कोनों को ले जाकर एक परत बदल सकता है GIMP, में समस्या को दर्शाता हुआ है। इसका परिणाम एक परिप्रेक्ष्य परिवर्तन में होता है। मैं एक क्यूटी आवेदन में बिल्कुल वही करना चाहता हूं। मुझे पता है कि क्यूट्रांसफॉर्म एफ़िन ट्रांसफॉर्मेशन तक ही सीमित नहीं है बल्कि परिप्रेक्ष्य परिवर्तनों को भी संभाल सकता है।

+0

नोट: मैं वर्तमान में समस्या को हल करने का प्रयास करता हूं। मैं पी 1 से शुरू होता हूं (जो मैप किए गए ऊपरी बाएं बिंदु (0,0) है): इसलिए मैं सिर्फ अनुवाद मैट्रिक्स का उपयोग करता हूं। स्केलिंग और कतरन मैट्रिक्स का उपयोग कर पी 2 और पी 3 तक पहुंचा जा सकता है। लेकिन मुझे पी 4 तक पहुंचने में समस्याएं हैं: मैं परिप्रेक्ष्य परिवर्तन के पीछे गणित को समझ नहीं पा रहा हूं और इस प्रकार यह नहीं जानता कि तीसरे कॉलम में मैट्रिक्स प्रविष्टियों की संख्या रूपांतरण को कैसे प्रभावित करती है। – leemes

उत्तर

2

आपको QTransform.squareToQuad के साथ ऐसा करने में सक्षम होना चाहिए। बस इसे QPolygonF पास करें जिसे आप बदलना चाहते हैं।

मुझे कभी-कभी स्क्वायर टॉक्वाड प्राप्त करने में कुछ समस्याएं होती हैं जो मुझे चाहिए, और मुझे अपने शुरुआती क्वाड को परिभाषित करने के बजाय QTransform.quadToQuad का उपयोग करना पड़ा, लेकिन आपको अधिक भाग्य हो सकता है।

+0

फिर से, बहुत बहुत धन्यवाद। अरे, मेरे गणित के साथ मेरा पूरा काम कुछ भी नहीं था ... :) – leemes

1

मुझे लगता है कि मुझे एक समाधान मिला है, जो चरण-दर-चरण रूपांतरण मैट्रिक्स की गणना करता है।

// some example points: 
QPointF p1(1.0, 2.0); 
QPointF p2(2.0, 2.5); 
QPointF p3(1.5, 4.0); 
QPointF p4(3.0, 5.0); 

// define the affine transformation which will position p1, p2, p3 correctly: 
QTransform trans; 
trans.translate(p1.x(), p1.y()); 
trans.scale(p2.x() - p1.x(), p3.y() - p1.y()); 
trans.shear((p3.x() - p1.x())/trans.m11(), (p2.y() - p1.y())/trans.m22()); 

अब तक, ट्रांस समानांतर परिवर्तन का वर्णन करता है। इस पैरालेलोग्राम के भीतर, मुझे अगले चरण में पी 4 (अपेक्षाकृत) मिलता है। मुझे लगता है कि यह एक प्रत्यक्ष सूत्र का उपयोग करके किया जा सकता है जिसमें ट्रांस का उलटा शामिल नहीं है।

// relative position of the 4th point in the transformed coordinate system: 
qreal px = trans.inverted().map(p4).x(); 
qreal py = trans.inverted().map(p4).y(); 

// this defines the perspective distortion: 
qreal y = 1 + (py - 1)/px; 
qreal x = 1 + (px - 1)/py; 

मूल्यों x और y की व्याख्या करने के लिए कड़ी मेहनत कर रहे हैं। उनमें से केवल एक को देखते हुए (दूसरा सेट 1), यह केवल p4 के सापेक्ष स्केलिंग को परिभाषित करता है। लेकिन एक्स और वाई दोनों परिप्रेक्ष्य परिवर्तन का संयोजन, एक्स और वाई का अर्थ मुश्किल है; मैंने परीक्षण और त्रुटि से सूत्रों को पाया।

// and thus the perspective matrix: 
QTransform persp(1/y, 0, 1/y-1, 
       0, 1/x, 1/x-1, 
       0, 0, 1); 

// premultiply the perspective matrix to the affine transformation: 
trans = persp * trans; 

कुछ परीक्षणों से पता चला कि इससे सही परिणाम मिलते हैं। हालांकि, मैंने विशेष मामलों का परीक्षण नहीं किया था, जहां दो अंक बराबर हैं या उनमें से एक दो अन्य लोगों के बीच रेखा खंड पर है; मुझे लगता है कि इस तरह की स्थितियों में यह समाधान टूट सकता है।

इसलिए, मैं अभी भी कुछ प्रत्यक्ष सूत्रों के लिए खोज मैट्रिक्स के लिए महत्व देता m11, m12 ... m33 बिंदु दिए गए निर्देशांक p1.x(), p1.y() ... p4.x(), p4.y()

+0

क्या आप QTransform.squareToQuad का उपयोग करने में सक्षम नहीं होना चाहिए? – dmd

+0

आहा, बहुत बहुत धन्यवाद @ डीएमडी, यह बिल्कुल वही है जो मैं खोज रहा था।मैंने आरटीएफएम पर्याप्त नहीं किया, या बेहतर कहा, समारोह का नाम पूरी तरह से ऐसा नहीं था जो मुझे इस तरह के एक समारोह के लिए अपेक्षित था जो वास्तव में मैं चाहता हूं! – leemes

+0

@dmd, अगर आप इसे उत्तर के रूप में लिखते हैं, तो मैं इसे स्वीकार करूंगा। – leemes

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

  • कोई संबंधित समस्या नहीं^_^