V.I.Smirnov Δημοσ. 15 Οκτωβρίου 2010 Δημοσ. 15 Οκτωβρίου 2010 @ V.I.Smirnov : Τα κοίταξα τελικά αυτά που μου έγραψες παραπάνω. Ουσιαστικά αυτό που πετυχαίνουμε είναι να μεγαλώσουμε την ευθεία μας ώστε να τέμνει κάποιο τοίχο και μετά υπολογίζουμε το σημείο τομής, έτσι δεν είναι..? Από τις έτοιμες συναρτήσεις της Qt (αν κατάλαβα καλά αυτά που λες) μπορούμε να το πετύχουμε αυτό αυξάνοντας το μέγεθος προς το δεύτερο σημείο με την setLength() τόσο ώστε σίγουρα να τέμνει κάποιο τοίχο και μετά με την intersect() να βρίσκαμε το σημείο αυτό.. σωστός τρόπος δεν είναι και αυτός..? απλά ήθελα να τον αποφύγω γιατί το να αυξήσω το μέγεθος μέχρι να φύγει από τα όρια της οθόνης μου φάνηκε λίγο "μπακαλίστικος" τρόπος..! Αλλά μάλλον δεν είναι. Αν κατάλαβα κάτι λάθος διόρθωσε με.. Κοίτα, αυτό που έδωσα είναι intersection για δύο τμήματα. Για την τομή δυο τμημάτων εξετάζεται καταρχήν η τομή των αντίστοιχων ευθειών τους, το έγραψα στο "Επιγραμματικά α)''. Αλλά το πώς δουλεύει εσωτερικά η ρουτίνα δεν χρειάζεται να το ξέρεις. Π.χ. για το β) υπάρχει κι' άλλος τρόπος. Το κόλπο με την προέκταση το πρότεινα για να μπορεί η ίδια ρουτίνα να εφαρμοστεί και σε τεστ ευθείας-τμήματος. Η ρουτίνα χρησιμοποιεί κάποια βοηθητικά τρίγωνα μια πλευρά του οποίων είναι το τμήμα που ορίζεται από τα δύο σημεία του ποντικιού. Όταν αυτό το τμήμα είναι πολύ μικρό μπορεί να εμφανιστούν προβλήματα ακρίβειας διότι η μια πλευρά του τριγώνου θα είναι πολύ μικρή σε σχέση με τις άλλες. Ως προς αυτό, ο εν λόγω τρόπος, ναι, είναι "μπακαλίστικος". Το σωστό είναι να γίνει εξαρχής intersection test μεταξύ ευθείας-τμήματος. Εγώ έδωσα τον συγκεκριμένο επειδή το test μεταξύ δυο τμημάτων είναι δυσκολότερο αλλά και επειδή το είχα ψάξει και είχα φτιάξει την ρουτίνα σε ψευδοκώδικα. Αυτό που λες παραπάνω δεν είναι ακριβώς έτσι. Μια ημιευθεία (εν προκειμένω πιο σωστά διανυσματική ακτίνα) έχει άπειρο μήκος. Αντίθετα, ο τοίχος είναι ένα τμήμα πεπερασμένου μήκους : έχει μήκος όσο είναι το οριζόντιο ή κατακόρυφο της οθόνης (σε pixel ή άλλη μονάδα μέτρησης). Γι αυτό μπορεί και να μην τέμνονται. Δηλ. αν προεκτείνεις την ευθεία που ορίζουν τα δυο σημεία του ποντικιού, αυτή δεν θα τέμνεται αναγκαστικά με τον τοίχο : μπορεί κάλλιστα να τον "προσπερνάει" απο πάνω ή από κάτω αφού αυτός δεν έχει άπειρο μήκος. Όσο λοιπόν κι αν προεκτείνεις την ευθεία με την setlength() η τομή της με τον τοίχο μπορεί να μην υπάρχει. Προφανώς αν ο τοίχος εκτεινόταν άπειρα, είχαμε ευθεία αντί ημιευθεία και δεν ήταν παράλληλα (ή ήταν αλλά ήταν και συγγραμμικά ταυτόχρονα), θα υπήρχε τομή πάντα. Τώρα όμως δεν συμβαίνει αυτό. Ένας καλός τρόπος για την τομή ακτίνας-τμήματος είναι ο εξής : α) Θεωρείς τα δυο σημεία του ποντικιού Α,Β και από αυτά την ευθεία που ορίζουν (παραμετρικά, δηλ. με το t). β) Όμοια, θεωρείς τα δυο σημεία του τοίχου C,D και από αυτά την ευθεία που ορίζουν (πάλι παραμετρικά, έστω με s). Τα C, D είναι τα άκρα της οθόνης σε κάθε πλευρά. Ούτε πιο μεγάλα, ούτε πιο μικρά γ) Βρίσκεις την τομή των ευθειών των A,B και C,D. Αυτό που ενδιαφέρει εδώ είναι οι τιμές των παραμέτρων t και s στο σημείο τομής για τις δυο ευθείες αντίστοιχα. Έστω ότι αυτές είναι to και so. δ) Θέτοντας μια από τις τιμές των παραμέτρων που βρήκες προηγουμένως (δηλ. τις to και so) στην αντίστοιχη παραμετρική εξίσωση ευθείας, βρίσκεις το σημείο τομής. Για ευθείες άπειρου μήκους οποιαδήποτε τιμή to και so είναι δεκτή. Εν προκειμένω όμως υπάρχουν δυο περιορισμοί. Αλλά με την παραμετρική γραφή εξετάζονται πολύ εύκολα. Για δες : i) το CD (δηλ. ο τοίχος που εξετάζεις) είναι πεπερασμένο, άρα το σημείο τομής πρέπει να βρίσκεται μεταξύ των C και D. Για συμβαίνει αυτό πρέπει το sο να είναι μεταξύ 0 και 1. Για οποιαδήποτε άλλη τιμή το σημείο τομής θα βρίσκεται στην προέκταση του CD είτε κατά την μεριά του C είτε κατά την μεριά του D και άρα απορρίπτεται (δεν υπάρχει τομή). ii) Σε ότι αφορά το AB, ενδιαφέρει να παίρνεις το σημείο τομής μόνον προς την κατεύθυνση του δεύτερου σημείου, δηλ. του B. Συνεπώς πρέπει να είναι to >=1 που σημαίνει ότι το σημείο τομής βρίσκεται από την μεριά του δεύτερου σημείου (δηλ. του Β) ή συμπίπτει με αυτό. Για τιμές to<1 αυτό δεν συμβαίνει άρα απορρίπτπεται (δεν υπάρχει τομή). Συνοψίζοντας αυτόν τον τρόπο : α) δίνεις τις συντεταγμένες των σημείων Α,Β,C,D και βρίσκεις τις to, so με εφαρμογή των τύπων β) ελέγχεις τους παραπάνω περιορισμούς γ) εφόσον ικανοποιούνται, θέτεις μια εκ των to, so στην αντίστοιχη εξίσωση και βρίσκεις το σημείο τομής (δηλ. πάνω στον τοίχο) O έλεγχος θα πρέπει να γίνεται για όλους τους τοίχους. Μένει μόνον να έχεις τους τύπους που δίνουν τα to και so, δηλ. τις λύσεις του συστήματος των δύο ευθειών σε παραμετρική μορφή. Δες τους στο παρακάτω zip. Eίναι από ένα τυπολόγιο γεωμετρίας μαζί με παράδειγμα χρήσης. (Στο παράδειγμα τα διανύσματα a και b δεν τα έχει σχεδιάσει καλά - μην μπερδευτείς !) Ξέρω και τις αποδείξεις αλλά δεν φαντάζομαι να σε ενδιαφέρουν. Αυτούς τους τύπους τους ξέρω και σε άλλη μορφή αλλά το τυπολόγιο αυτό τους δίνει "ready to use". Σε ότι αφορά αυτό που λέει ο gtroza για το συμμετρικό, είναι κλασικό πρόβλημα γεωμετρίας : Δίνεται η εξίσωση μιας ευθείας και ένα σημείο Α και ζητείται το συμμετρικό του σημείου Α, έστω Α', ως προς την ευθεία. Η λύση είναι αυτή που λέει ο gtroza : α) βρίσκεις ευθεία που διέρχεται από το Α και είναι κάθετη στην αρχική β) βρίσκεις το σημείο τομής των δυο ευθειών, έστω Κ γ) το συμμετρικό Α' βρίσκεται χρησιμοποιώντας ότι το Κ είναι μέσο του ΑΑ' Το έλυσα αλγεβρικά και βρήκα τον τελικό τύπο αλλά να μην τον γράφω τώρα. Αν επιμένεις να το χρησιμοποιήσεις και δεν τα καταφέρεις να το βρεις, πες μας να σου τον δώσω. Αλλά ο τρόπος που έγραψα παραπάνω μου φαίνεται καλύτερος και προσωπικά εκείνον θα εφάρμοζα... - geometry.zip
gtroza Δημοσ. 15 Οκτωβρίου 2010 Δημοσ. 15 Οκτωβρίου 2010 καλημέρα σε δάσκαλο και μαθητή ! ελπίζω χωρίς παρεξήγηση ! για karabouzouk το Qcad είναι υλοποιημένο με QT και c στον κώδικά του θα βρείς σίγουρα για mirror το Thancad είναι υλοποιημένο σε python κι αυτό πρέπει να έχει mirror , edit:έχει το αναπτύσσει ο Θανάσης Στάμος καί τα δυο έχουν intersection .
V.I.Smirnov Δημοσ. 15 Οκτωβρίου 2010 Δημοσ. 15 Οκτωβρίου 2010 καλημέρασε δάσκαλο και μαθητή ! Καλημέρα !! Μακάρι να ήμουν δάσκαλος αλλά δυστυχώς δεν.....
karabouzouk... Δημοσ. 17 Οκτωβρίου 2010 Μέλος Δημοσ. 17 Οκτωβρίου 2010 Τα ξενύχτια μου και τα διανύσματα μου μέσα..!! Η απάντηση σε όλες αυτές τις σελίδες είναι: reflexray.setAngle(walls.at(wallcount).angle() + starttocursor.angleTo(walls.at(wallcount))); Πέρα από τα σχόλια χαράς που βρήκα μια λύση.. Καθώς προσπαθούσα να καταλάβω τα διανύσματα και να τα εφαρμόσω είδα (προς απογοήτευση σας) ότι δεν τα πολυκαταφέρνω και σκέφτηκα να δω τι παίζει με τη λύση που είχα σκεφτεί στην αρχή με τις γωνίες.. και να σου η συνάρτηση setAngle()(μετακινεί το δεύτερο σημείο του διανύσματος τόσο ώστε να έχουμε τη γωνία που θέλουμε (μετριέται από τη θέση "3 η ώρα" και αντίθετα από τη φορά του ρολογιού)) ήρθε να μου λύσει τα χέρια.. Και με τη βοήθεια των angle() (επιστρέφει τη γωνία του διανύσματος από την οριζόντια θέση) και angleTo()(επιστρέφει τη γωνία από μεταξύ δύο διανυσμάτων) η δουλεία καλός η κακός έγινε.. θα ανεβάσω και τον κώδικα αν θέλετε να εφαρμόσετε τη μέθοδο με τα διανύσματα (σιγά μην θέλετε ) αλλά και να τον χρησιμοποιήσετε, βελτιώσετε, πάρετε ιδέες) Ευχαριστώ για την βοήθεια σας και τον χρόνο σας! ότι άλλο χρειαστώ θα το ρωτήσω εδώ.
gtroza Δημοσ. 17 Οκτωβρίου 2010 Δημοσ. 17 Οκτωβρίου 2010 Thanks karabouzouk! άκυρο ατυχές σχόλιο δυστυχώς ο νέος είν' ωραίος! Γενικά θα υπάρχει ένα σημείο (μαύρη τελεία) που θα ορίζω εγώ τη θέση του και από κει θα ξεκινάει η γραμμή, η οποία θα περνάει από τη θέση του κέρσορα του ποντικιού (βελάκι), στη συνέχεια θα καταλήγει σε ένα όριο που πάλι θα ορίζω εγώ τη θέση του (μαύρη κάθετη γραμμή), και τέλος θα συνεχίζει την πορεία της κάνοντας κάτι σαν ανάκλαση στο όριο που έχω θέσει.. (άρα πρέπει a=. για διαφορετικά πράγματα μιλούσαμε !:mrgreen::mrgreen: αύριο η συνέχεια .
karabouzouk... Δημοσ. 17 Οκτωβρίου 2010 Μέλος Δημοσ. 17 Οκτωβρίου 2010 για διαφορετικά πράγματα μιλούσαμε !:mrgreen::mrgreen: Δε νομίζω ότι μιλούσαμε για διαφορετικά.. κοίτα να σου πω την αλήθεια το σχέδιό σου ήταν λίγο διαφορετικό από αυτό που περιέγραφα εγώ αλλά αφού κατάλαβα τι εννοείς και τον τρόπο που περιέγραφες για το σχηματισμό της ανακλώμενης δεν έδωσα σημασία στις λεπτομέρειες αφού έτσι κι αλλιώς δεν ήταν σε αυτές η ουσία..!
gtroza Δημοσ. 17 Οκτωβρίου 2010 Δημοσ. 17 Οκτωβρίου 2010 τέλος καλό όλα καλά! αλλά δεν είναι ίδια αυτό εννοούσες; .
gtroza Δημοσ. 17 Οκτωβρίου 2010 Δημοσ. 17 Οκτωβρίου 2010 τέλος καλό όλα καλά! αλλά δεν είναι ίδια αυτό εννοούσες; .
karabouzouk... Δημοσ. 19 Οκτωβρίου 2010 Μέλος Δημοσ. 19 Οκτωβρίου 2010 Ακριβώς αυτό εννοούσα....!! Αλλά το από που θα ξεκινάει κλπ δεν έχει σημασία.. το πως θα γίνει η αντανάκλαση ήταν το πρόβλημα και η λύση σου ήταν σωστή.. Με αυτό τον τρόπο που είπες δεν το έκανες..? Μόλις διορθώσω αυτό που έκανα εγώ γιατί δεν δουλεύει ακριβώς όπως πρέπει θα το βάλω εδώ.
karabouzouk... Δημοσ. 19 Οκτωβρίου 2010 Μέλος Δημοσ. 19 Οκτωβρίου 2010 Ακριβώς αυτό εννοούσα....!! Αλλά το από που θα ξεκινάει κλπ δεν έχει σημασία.. το πως θα γίνει η αντανάκλαση ήταν το πρόβλημα και η λύση σου ήταν σωστή.. Με αυτό τον τρόπο που είπες δεν το έκανες..? Μόλις διορθώσω αυτό που έκανα εγώ γιατί δεν δουλεύει ακριβώς όπως πρέπει θα το βάλω εδώ.
V.I.Smirnov Δημοσ. 19 Οκτωβρίου 2010 Δημοσ. 19 Οκτωβρίου 2010 Tι δεν δουλεύει όπως πρέπει ; Είπες ότι το βρήκες.
V.I.Smirnov Δημοσ. 19 Οκτωβρίου 2010 Δημοσ. 19 Οκτωβρίου 2010 Tι δεν δουλεύει όπως πρέπει ; Είπες ότι το βρήκες.
karabouzouk... Δημοσ. 19 Οκτωβρίου 2010 Μέλος Δημοσ. 19 Οκτωβρίου 2010 Tι δεν δουλεύει όπως πρέπει ; Είπες ότι το βρήκες. Υποθέτω ότι κάτι δεν πάει καλά με τις μεταβλητές κλπ αλλά δεν είχα το χρόνο να το κοιτάξω μέχρι τώρα.. για το σχεδιασμό μιάς ανακλώμενης δουλεύει κανονικά αλλά όταν πάω να το εφαρμόσω και για περισσότερες τότε κάτι δεν πάει καλά.. Ορίστε ο κώδικας στα χάλια που είναι τώρα ίσως δείτε κάτι που δεν βλέπω εγώ. > #include <QtGui> class MyWidget : public QWidget { public: MyWidget(); private: QList <QLineF> walls; QList <QLineF> reflexingLines; QLineF tempLine; int repainttimer/*time between refreshes*/, refreshrate/*in Hz*/, timerID, maxReflexingLines; int count, reflexingwall, prevreflexingwall; QPointF cursorpos, startpos, curRayStartPos; QPointF intersectionpoint, tempintersectionpoint; double maxlength, minraylength; protected: void paintEvent(QPaintEvent *); void timerEvent(QTimerEvent *); void keyPressEvent(QKeyEvent *); void resizeEvent(QResizeEvent *); }; MyWidget::MyWidget() { refreshrate = 40; repainttimer = 1000/refreshrate; timerID = startTimer(repainttimer); maxReflexingLines = 3; startpos = QPoint(200, 300); } void MyWidget::resizeEvent(QResizeEvent *){ walls.clear(); walls << QLine (100, 50, 400, 600); walls << QLineF(rect().topRight(), rect().bottomRight()); walls << QLineF(rect().bottomRight(), rect().bottomLeft()); walls << QLineF(rect().bottomLeft(), rect().topLeft()); walls << QLineF(rect().topLeft(), rect().topRight()); walls << QLine (50, 50, 500, 500); maxlength = rect().width() + rect().height(); } void MyWidget::keyPressEvent(QKeyEvent *keyevent){ if(keyevent->key()==(Qt::Key_S)){ startpos = cursorpos; } if(keyevent->key()==(Qt::Key_W)){ } //increase refresh rate an restart timer. if(keyevent->key()==(Qt::Key_M)){ refreshrate+=1; repainttimer = 1000/refreshrate; killTimer(timerID); timerID = startTimer(repainttimer); } //Decrease refresh rate and restart timer. if(keyevent->key()==(Qt::Key_L)){ if (refreshrate > 1) refreshrate-=1; repainttimer = 1000/refreshrate; killTimer(timerID); timerID = startTimer(repainttimer); } } void MyWidget::timerEvent(QTimerEvent *){ QLineF::IntersectType interType; //if(mapFromGlobal(QCursor::pos()) != raytocursor.topLeft()){ cursorpos = mapFromGlobal(QCursor::pos()); reflexingLines.clear(); reflexingLines << QLineF(startpos, cursorpos); reflexingLines[0].setLength(maxlength); curRayStartPos.setX(startpos.x()); curRayStartPos.setY(startpos.y()); minraylength = maxlength; prevreflexingwall = -1; for (count=0; count < maxReflexingLines-1; count++){ for(int i=0; i<walls.size(); i++){ if(i != prevreflexingwall){ interType = reflexingLines.at(count).intersect(walls.at(i), &tempintersectionpoint); if (interType == 1){ if (QLineF(curRayStartPos, tempintersectionpoint).length() < minraylength){ minraylength = QLineF(curRayStartPos, tempintersectionpoint).length(); intersectionpoint = tempintersectionpoint; reflexingwall = i; } } } } prevreflexingwall = reflexingwall; curRayStartPos.setX(intersectionpoint.x()); curRayStartPos.setY(intersectionpoint.y()); reflexingLines[count].setP2(intersectionpoint); // tempLine.setLine(intersectionpoint.x(), intersectionpoint.y(), 0, 0); // tempLine.setLength(maxlength); // tempLine.setAngle(walls[reflexingwall].angle() + reflexingLines[count].angleTo(walls[reflexingwall])); // reflexingLines << tempLine; reflexingLines.append(QLineF(intersectionpoint.x(), intersectionpoint.y(), 0, 0)); reflexingLines.last().setAngle(walls[reflexingwall].angle() + reflexingLines[count].angleTo(walls[reflexingwall])); reflexingLines.last().setLength(maxlength); } //reflexingLines.last().setP2(intersectionpoint); update(); //repaint(); //} } void MyWidget::paintEvent(QPaintEvent *) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.setPen(Qt::black); for (int i=0; i<reflexingLines.size(); i++){ painter.drawLine(reflexingLines.at(i)); } //painter.drawLine(tempLine); painter.setPen(Qt::red); painter.drawEllipse(intersectionpoint, 30,30); painter.setPen(Qt::yellow); painter.drawEllipse(curRayStartPos, 30,30); painter.setPen(Qt::blue); for (int i=0; i<walls.size(); i++){ painter.drawLine(walls.at(i)); } //make mask in order mouse can click throught it. QRegion r1(rect()); QRegion r2(QRect(cursorpos.x()-2, cursorpos.y()-2, 5, 5)); QRegion r3(r1.xored(r2)); setMask(r3); //draw statistics on the right of the screen.// QString strx, stry, repainttimerstr, refreshratestr; strx.setNum(cursorpos.x(), 'g', 10); stry.setNum(cursorpos.y(), 'g',10); repainttimerstr.setNum(repainttimer, 10); refreshratestr.setNum(refreshrate, 10); painter.drawText(rect(), Qt::AlignVCenter | Qt::AlignRight, strx + " , " + stry + " \n" + refreshratestr + "Hz, " + repainttimerstr + "msec \n "); //painter.drawText(cursorpos, strx + " , " + stry); } int main(int argc, char *argv[]) { QApplication app(argc, argv); MyWidget w1; //w1.setUpdatesEnabled(true); //w1.setWindowOpacity(1); w1.setMouseTracking(true); w1.setAttribute(Qt::WA_TranslucentBackground); w1.setWindowFlags(Qt::WindowStaysOnTopHint); //w1.setAutoFillBackground(false); w1.showMaximized(); //w1.show(); //w1.showFullScreen(); w1.setFocus(); return app.exec(); } Αν το τρέξετε η μεταβλητή maxReflexingLines είναι αυτή που λέει πόσες ανακλώμενες θα υπολογιστούν για να την αλλάξετε. Όποια άλλη απορία σχετικά με τον κώδικα ρωτήστε με για να μην χαθείτε προσπαθώντας να τον καταλάβετε. Με το "Μ" και το "L" αλλάζει η συχνότητα ανανέωσης αν ο υπολογιστής σας δυσκολεύεται.. είναι ορισμένο στα 40Hz.
karabouzouk... Δημοσ. 19 Οκτωβρίου 2010 Μέλος Δημοσ. 19 Οκτωβρίου 2010 Tι δεν δουλεύει όπως πρέπει ; Είπες ότι το βρήκες. Υποθέτω ότι κάτι δεν πάει καλά με τις μεταβλητές κλπ αλλά δεν είχα το χρόνο να το κοιτάξω μέχρι τώρα.. για το σχεδιασμό μιάς ανακλώμενης δουλεύει κανονικά αλλά όταν πάω να το εφαρμόσω και για περισσότερες τότε κάτι δεν πάει καλά.. Ορίστε ο κώδικας στα χάλια που είναι τώρα ίσως δείτε κάτι που δεν βλέπω εγώ. > #include <QtGui> class MyWidget : public QWidget { public: MyWidget(); private: QList <QLineF> walls; QList <QLineF> reflexingLines; QLineF tempLine; int repainttimer/*time between refreshes*/, refreshrate/*in Hz*/, timerID, maxReflexingLines; int count, reflexingwall, prevreflexingwall; QPointF cursorpos, startpos, curRayStartPos; QPointF intersectionpoint, tempintersectionpoint; double maxlength, minraylength; protected: void paintEvent(QPaintEvent *); void timerEvent(QTimerEvent *); void keyPressEvent(QKeyEvent *); void resizeEvent(QResizeEvent *); }; MyWidget::MyWidget() { refreshrate = 40; repainttimer = 1000/refreshrate; timerID = startTimer(repainttimer); maxReflexingLines = 3; startpos = QPoint(200, 300); } void MyWidget::resizeEvent(QResizeEvent *){ walls.clear(); walls << QLine (100, 50, 400, 600); walls << QLineF(rect().topRight(), rect().bottomRight()); walls << QLineF(rect().bottomRight(), rect().bottomLeft()); walls << QLineF(rect().bottomLeft(), rect().topLeft()); walls << QLineF(rect().topLeft(), rect().topRight()); walls << QLine (50, 50, 500, 500); maxlength = rect().width() + rect().height(); } void MyWidget::keyPressEvent(QKeyEvent *keyevent){ if(keyevent->key()==(Qt::Key_S)){ startpos = cursorpos; } if(keyevent->key()==(Qt::Key_W)){ } //increase refresh rate an restart timer. if(keyevent->key()==(Qt::Key_M)){ refreshrate+=1; repainttimer = 1000/refreshrate; killTimer(timerID); timerID = startTimer(repainttimer); } //Decrease refresh rate and restart timer. if(keyevent->key()==(Qt::Key_L)){ if (refreshrate > 1) refreshrate-=1; repainttimer = 1000/refreshrate; killTimer(timerID); timerID = startTimer(repainttimer); } } void MyWidget::timerEvent(QTimerEvent *){ QLineF::IntersectType interType; //if(mapFromGlobal(QCursor::pos()) != raytocursor.topLeft()){ cursorpos = mapFromGlobal(QCursor::pos()); reflexingLines.clear(); reflexingLines << QLineF(startpos, cursorpos); reflexingLines[0].setLength(maxlength); curRayStartPos.setX(startpos.x()); curRayStartPos.setY(startpos.y()); minraylength = maxlength; prevreflexingwall = -1; for (count=0; count < maxReflexingLines-1; count++){ for(int i=0; i<walls.size(); i++){ if(i != prevreflexingwall){ interType = reflexingLines.at(count).intersect(walls.at(i), &tempintersectionpoint); if (interType == 1){ if (QLineF(curRayStartPos, tempintersectionpoint).length() < minraylength){ minraylength = QLineF(curRayStartPos, tempintersectionpoint).length(); intersectionpoint = tempintersectionpoint; reflexingwall = i; } } } } prevreflexingwall = reflexingwall; curRayStartPos.setX(intersectionpoint.x()); curRayStartPos.setY(intersectionpoint.y()); reflexingLines[count].setP2(intersectionpoint); // tempLine.setLine(intersectionpoint.x(), intersectionpoint.y(), 0, 0); // tempLine.setLength(maxlength); // tempLine.setAngle(walls[reflexingwall].angle() + reflexingLines[count].angleTo(walls[reflexingwall])); // reflexingLines << tempLine; reflexingLines.append(QLineF(intersectionpoint.x(), intersectionpoint.y(), 0, 0)); reflexingLines.last().setAngle(walls[reflexingwall].angle() + reflexingLines[count].angleTo(walls[reflexingwall])); reflexingLines.last().setLength(maxlength); } //reflexingLines.last().setP2(intersectionpoint); update(); //repaint(); //} } void MyWidget::paintEvent(QPaintEvent *) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.setPen(Qt::black); for (int i=0; i<reflexingLines.size(); i++){ painter.drawLine(reflexingLines.at(i)); } //painter.drawLine(tempLine); painter.setPen(Qt::red); painter.drawEllipse(intersectionpoint, 30,30); painter.setPen(Qt::yellow); painter.drawEllipse(curRayStartPos, 30,30); painter.setPen(Qt::blue); for (int i=0; i<walls.size(); i++){ painter.drawLine(walls.at(i)); } //make mask in order mouse can click throught it. QRegion r1(rect()); QRegion r2(QRect(cursorpos.x()-2, cursorpos.y()-2, 5, 5)); QRegion r3(r1.xored(r2)); setMask(r3); //draw statistics on the right of the screen.// QString strx, stry, repainttimerstr, refreshratestr; strx.setNum(cursorpos.x(), 'g', 10); stry.setNum(cursorpos.y(), 'g',10); repainttimerstr.setNum(repainttimer, 10); refreshratestr.setNum(refreshrate, 10); painter.drawText(rect(), Qt::AlignVCenter | Qt::AlignRight, strx + " , " + stry + " \n" + refreshratestr + "Hz, " + repainttimerstr + "msec \n "); //painter.drawText(cursorpos, strx + " , " + stry); } int main(int argc, char *argv[]) { QApplication app(argc, argv); MyWidget w1; //w1.setUpdatesEnabled(true); //w1.setWindowOpacity(1); w1.setMouseTracking(true); w1.setAttribute(Qt::WA_TranslucentBackground); w1.setWindowFlags(Qt::WindowStaysOnTopHint); //w1.setAutoFillBackground(false); w1.showMaximized(); //w1.show(); //w1.showFullScreen(); w1.setFocus(); return app.exec(); } Αν το τρέξετε η μεταβλητή maxReflexingLines είναι αυτή που λέει πόσες ανακλώμενες θα υπολογιστούν για να την αλλάξετε. Όποια άλλη απορία σχετικά με τον κώδικα ρωτήστε με για να μην χαθείτε προσπαθώντας να τον καταλάβετε. Με το "Μ" και το "L" αλλάζει η συχνότητα ανανέωσης αν ο υπολογιστής σας δυσκολεύεται.. είναι ορισμένο στα 40Hz.
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.