Προς το περιεχόμενο

Qt σχεδίαση γραμμών σε σχέση με τη θέση του ποντικιού


karabouzouk...

Προτεινόμενες αναρτήσεις

Τώρα παρατήρησα ένα άλλο λάθος στο βιντεάκι.. η ακτίνα δεν ανακλάται σωστά... καταλήγει πάντα στο ίδιο σημείο όσο και να αλλάζει η κατεύθυνση της αρχικής ακτίνας..!

 

Αυτό συμβαίνει διότι έτσι ερμήνευσα την παρατήρηση της αρχικής σου ανάρτησης:

[..]και τέλος θα συνεχίζει την πορεία της κάνοντας κάτι σαν ανάκλαση στο όριο που έχω θέσει.. (άρα πρέπει a=B).

 

Οπότε για τις ανάγκες του παραδείγματος το θεώρησα αρκετό.

 

Φυσικά καθώς ο κώδικας έχει αναρτηθεί μπορεί να τροποποιηθεί κατά το δοκούν.

:-)

 

--

 

@gtroza: Thx! Το είδα σαν μια άριστη ευκαιρία να ασχοληθώ λίγο με γεωμετρία / τριγωνομετρία κτλ. έτσι για να δω "τι παίζει" που λέμε καθώς δεν ασχολούμαι με αυτό το άθλημα :-D

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • Απαντ. 73
  • Δημ.
  • Τελ. απάντηση
http://gtroza-cad-program.blogspot.com/2010/09/problem.html

δεν είναι τέλειο

αλλά δεν είμαι του "χώρου" !:mrgreen:

.

Δεν ξέρω αν με ξεγελάει το βίντεο αλλά όντως φαίνεται πιο γρήγορο απ αυτό του Directx.. δεν κάνει καθόλου σπασήματα.. Αλλά μια ερώτηση, υπάρχει τρόπος να έχω τη δυνατότητα που είπα και στην αρχή να αλληλεπιδρώ με αντικείμενα που βρίσκονται πίσω από το παράθυρο που εκτελείται το πρόγραμμα..?

 

 

Αυτό συμβαίνει διότι έτσι ερμήνευσα την παρατήρηση της αρχικής σου ανάρτησης

 

Οπότε για τις ανάγκες του παραδείγματος το θεώρησα αρκετό.

 

Φυσικά καθώς ο κώδικας έχει αναρτηθεί μπορεί να τροποποιηθεί κατά το δοκούν.

:-)

Απλά το παρατήρησα και το επισήμανα..! Ο κώδικας έτσι κι αλλιώς είναι ότι πρέπει για να κάνω αυτό που θέλω με λίγες αλλαγές!

 

@V.I.Smirnov: thnx για την παρατήρηση και την επεξήγηση!

 

Να και οι πρωτες βιντεοαπαντησεις :-D

forum με δυνατότητα απάντησης μόνο με video.. πολύ καλή ιδέα..!

 

 

Εγώ ωστόσο ακόμα να βγάλω άκρη για το πως θα κάνω αυτό που θέλω με το διάφανο παράθυρο.. Και ούτε καν ξέρω αν κάτι τέτοιο είναι δυνατόν με το Qt..

 

Διαφωτίστε με....!

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Έχω φτάσει σε αυτό το σημείο στις δοκιμές μου..

+τα σχήματα σχεδιάζονται..

+το παράθυρο είναι ένα QWidget που του έχω ορίσει ένα τετράγωνο QRegion (πάνω αριστερά) όπου και φαίνονται τα σχέδια που έχω φτιάξει.

+Μέσα από το υπόλοιπο παράθυρο μπορώ να αλληλεπιδράσω με το φόντο, αλλά σε αυτή την περιοχή δεν φαίνονται τα σχήματα.

 

έχω κολλήσει στα:

-το always on top το κάνω χειροκίνητα (δεξί κλικ στο παράθυρο κλπ) κάποια συνάρτηση υπάρχει αλλά δεν την έχω βρεί.. (βρέθηκε!)

-τα σχήματα δεν σχεδιάζονται στο μέρος του παραθύρου όπου μπορώ να αλληλεπιδράσω με τα πίσω παράθυρα. (Δεν ξέρω γιατί αλλά μου φαίνεται και δύσκολο να γίνει...)

-επίσης τα είχα βρεί και παλούκια όταν προσπάθησα να παίρνω τις συντεταγμένες του ποντικιού κάθε φορά που αυτό κινείται..

 

Όποια βοήθεια στα παραπάνω θα είναι σωτήρια...!

 

>#include <QtGui>


class MyWidget : public QWidget
{
public:
   MyWidget();

protected:
   void paintEvent(QPaintEvent *);
};

MyWidget::MyWidget()
{
   QPalette palette(MyWidget::palette());
   palette.setColor(backgroundRole(), Qt::white);
   setPalette(palette);
}

void MyWidget::paintEvent(QPaintEvent *)
{
   QPainter painter(this);
   painter.setRenderHint(QPainter::Antialiasing);
   painter.setPen(Qt::darkGreen);
   painter.drawRect(40, 40, 200,200);
   painter.setPen(Qt::darkGray);
   painter.drawLine(20, 20, 300,300);
}

int main(int argc, char *argv[])
{
   QApplication app(argc, argv);
   MyWidget w1;

   QRegion r2(QRect(0, 0, 200, 200));
   w1.setMask(r2);
   w1.setWindowOpacity(0.8);
   w1.setWindowFlags(Qt::WindowStaysOnTopHint);

   w1.show();

   return app.exec();
}

post-69920-129063124788_thumb.jpg

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δεν ξέρω αν με ξεγελάει το βίντεο αλλά όντως φαίνεται πιο γρήγορο απ αυτό του Directx.. δεν κάνει καθόλου σπασήματα.. Αλλά μια ερώτηση, υπάρχει τρόπος να έχω τη δυνατότητα που είπα και στην αρχή να αλληλεπιδρώ με αντικείμενα που βρίσκονται πίσω από το παράθυρο που εκτελείται το πρόγραμμα..?

σε tcl/tk, δεν ξέρω αν γίνεται, αλλά μάλλον όχι

 

αποσύρω τα επαινετικά σχόλια για την γλώσσα !

και παραδίνομαι μπροστά στη δύναμη των guru !

:mrgreen:

 

.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Προς χάριν πληρότητας του θέματος και καθώς διαθέτω το Nokia QT SDK εγκατεστημένο αποφάσισα να δοκιμάσω ένα όσο το δυνατόν πιο απλό port του κώδικα της VCL στο Nokia QT SDK, ως προσωπική εξάσκηση σε αυτό το ισχυρότατο framework (ο κώδικας βγήκε αρκετά compact!).

 

Αυτό σημαίνει ότι ο κώδικας εκτελείται σε έναν ειδικό simulator που προσφέρει το Nokia QT IDE, ο οποίος μιμείται ένα κινητό τηλέφωνο Nokia, με SYMBIAN 5th Edition.

 

Δυστυχώς δεν έχω εγκαταστήσει τις απαραίτητες βιβλιοθήκες του QT για ανάπτυξη desktop εφαρμογών οπότε δεν μπορώ να γνωρίζω αν ο κώδικας που ακολουθεί εκτελείται σωστά ως τυπική εφαρμογή Windows ή να ψάξω πως μπορεί να επιτευχθεί διαφάνεια κτλ. Επίσης σημειώνω ότι δεν διαθέτω ανάλογο κινητό τηλέφωνο προς δοκιμή του σε πραγματικό hardware ενώ δεν ασχολούμαι εκτεταμένα με το Qt (ευκαιρία να αρχίσω! :-D).

 

Το πρόγραμμα έχει διάφορες αβλεψίες όσον αφορά την γεωμετρία κτλ αλλά όπως εξήγησα δεν ασχολούμαι με το άθλημα, αλλά ίσως φανεί χρήσιμο οπότε και το αναρτώ.

 

mainwindow.ui: (η φόρμα σχεδιασμένη με τον Form Editor του Qt Creator 2.0 - το IDE κάνει με βάση αυτήν autogenerate το ui_mainwindow.h όπου χρειασθεί)

>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
 <property name="geometry">
  <rect>
   <x>0</x>
   <y>0</y>
   <width>360</width>
   <height>640</height>
  </rect>
 </property>
 <property name="windowTitle">
  <string>MainWindow</string>
 </property>
 <widget class="QWidget" name="centralWidget"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

 

mainwindow.h:

>
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPaintEvent>
#include <QMouseEvent>
#include <QTimerEvent>
#include <QKeyEvent>
#include <QRect>

namespace Ui {
   class MainWindow;
}

class MainWindow : public QMainWindow
{
   Q_OBJECT

public:
   explicit MainWindow(QWidget *parent = 0);
   ~MainWindow();

private:
   Ui::MainWindow *ui;
   QRect rcDot, rcWall, rcRay;
   float Angle;
   int TimerID;

   void paintEvent(QPaintEvent *);
   void mousePressEvent(QMouseEvent *);
   void keyPressEvent(QKeyEvent *);
   void timerEvent(QTimerEvent *);
};

#endif // MAINWINDOW_H

 

mainwindow.cpp:

>
/*
* Draw with QT (c) directx.
*/
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QPainter>
#include <QBrush>
#include <QPen>
#include <QDebug>
#include <math.h>

MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
   // Init. variables.
   Angle = 0;

   rcDot = QRect(1, 1, 31, 31);
   rcWall= QRect(1, 1, 1, 101);
   // Start internal timer.
   TimerID = startTimer(100);
   // Setup UI (autogenerated).
   ui->setupUi(this);
}

MainWindow::~MainWindow()
{
   killTimer(TimerID);
   delete ui;
}

void MainWindow::paintEvent(QPaintEvent *event)
{
   QPainter Painter(this);
   // Render Help Text.
   Painter.fillRect(rect(), Qt::blue);
   Painter.drawText(rect(), (QString)"PRESS LEFT BUTTON TO SET DOT\n" +
                                     "PRESS RIGHT BUTTON TO SET WALL\n"+
                                     "PRESS LEFT KEY TO MOVE DOT CLOCKWISE\n"+
                                     "PRESS RIGHT KEY TO MOVE DOT ANTICLOCKWISE",
                                     QTextOption(Qt::AlignCenter)
                                     );

   // Render Dot.
   Painter.setPen(QPen(Qt::red));
   Painter.setBrush(QBrush(Qt::red));
   Painter.drawEllipse(rcDot);
   // Render Wall.
   Painter.setPen(QPen(Qt::white));
   Painter.drawLine(rcWall.left(), rcWall.top(),
                    rcWall.right(), rcWall.bottom());
   // Calculate Ray (naive rotation).
   rcRay = QRect(rcDot.center().x(),
                 rcDot.center().y(),
                 rect().height() * (cos(Angle * 0.017453292)) + 1,
                 rect().height() * (sin(Angle* 0.017453292)) + 1
                 );
   //qDebug() << rcRay;
   // Calculate Ray to Wall intersection.
   QLineF RayLine = QLineF(rcRay.left(),
                           rcRay.top(),
                           rcRay.right(),
                           rcRay.bottom());
   QLineF WallLine= QLineF(rcWall.left(),
                           rcWall.top(),
                           rcWall.right(),
                           rcWall.bottom());
   QPointF IPoint;
   if(RayLine.intersect(WallLine, &IPoint) == QLineF::BoundedIntersection)
   {
       // Absorb Ray on Wall..
       rcRay.setRight(IPoint.x());
       rcRay.setBottom(IPoint.y());
       // Render Reflection (naive way).
       Painter.setPen(QPen(Qt::green));
       Painter.drawLine(IPoint.x(), IPoint.y(),
                        rcRay.left(), rcRay.bottom() + rect().height());
   }
   // Render Ray.
   Painter.setPen(QPen(Qt::yellow));
   Painter.drawLine(rcRay.left(), rcRay.top(),
                    rcRay.right(), rcRay.bottom());
   //qDebug() << Angle;
}
void MainWindow::mousePressEvent(QMouseEvent *event)
{
   event->accept();

   // Set Dot location?
   if(event->button() == Qt::LeftButton)
       rcDot = QRect(event->pos().x() - 15,
                     event->pos().y() - 15,
                     30,
                     30);
   // Set Wall location?
   if(event->button() == Qt::RightButton)
       rcWall = QRect(event->pos().x(),
                      event->pos().y(),
                      1,
                      100);
}
void MainWindow::keyPressEvent(QKeyEvent *event)
{
   event->accept();

   // Rotate Ray clockwise.
   if(event->key() == Qt::Key_Left)
       Angle += (float)5;
   // Rotate Ray anti-clockwise.
   if(event->key() == Qt::Key_Right)
       Angle -= (float)5;
}

void MainWindow::timerEvent(QTimerEvent *event)
{
   // Update QWidget.
   repaint();
}

 

Σημ.: Η μετακίνηση του κύκλου γίνεται με αριστερό κλικ, η μετακίνηση του τοίχου με δεξιό και η περιστροφή της ακτίνας με το δεξί και αριστερό βελάκι του πληκτρολογίου (κανονικά το Qt προσφέρει ένα wheelEvent ως virtual function αλλά δεν αντιδρούσε στον Simulator οπότε..).

Η μεταγλώττιση έγινε με την βοήθεια του VS2008 C++ compiler κάτω από το QT Creator 2.0 IDE.

 

Ακολουθεί και ένα βιντεάκι:

[ame=http://www.youtube.com/watch?v=mbl014m24WM]βίντεο[/ame]

 

Υ.Γ.

Τα σπασίματα στην εκδοχή της VCL οφείλονται σε μη χρήση double-buffer.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Έχω κάνει άπειρες προσπάθειες και δεν μπορώ να πετύχω αυτό που θέλω..

Υπάρχει η συνάρτηση createMaskFromColor() της κλάσης QPixmap που δίνοντας της σαν παράμετρο το χρώμα δημιουργεί μια μάσκα (είναι η μαγκιά που ενδιάμεσα της βλέπεις τα πίσω παράθυρα και μπορείς να αλληλεπιδράσεις με αυτά) με βάση το χρώμα, δλδ όπου είναι ίδιο το χρώμα το κάνει διάφανο (ή όπου δεν είναι ίδιο το χρώμα, ορίζεται και αυτό με παράμετρο).

Το θέμα είναι ότι παρ όλα αυτά δεν έχω καταφέρει να το κάνω να δουλέψει ακόμα.. δεν ξέρω τι κάνω λάθος.. πρέπει να είναι προγραμματιστικό απ ότι καταλαβαίνω..

όποιος μπορεί ας ρίξει μια ματιά..

 

>#include <QtGui>

class MyWidget : public QWidget
{
public:
   MyWidget();

protected:
   void paintEvent(QPaintEvent *);
};


MyWidget::MyWidget()
{
}



void MyWidget::paintEvent(QPaintEvent *)
{
   QPixmap pix(size());
   QPainter painter(this);

   painter.setRenderHint(QPainter::Antialiasing);
   painter.setPen(Qt::darkGreen);
   painter.drawRect(40, 40, 200,200);
   painter.drawLine(20, 20, 300,300);
   painter.redirected(&pix);
   painter.drawLine(40, 40, 200,400);
   QRegion r2(pix.createMaskFromColor(Qt::darkGreen,Qt::MaskOutColor));
   setMask(r2);
}

int main(int argc, char *argv[])
{
   QApplication app(argc, argv);
   MyWidget w1;
   
   //w1.setWindowOpacity(0.8);
   w1.setMouseTracking(true);

   w1.setWindowFlags(Qt::WindowStaysOnTopHint);
   w1.showMaximized();

   return app.exec();
}

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Έχω κάνει άπειρες προσπάθειες και δεν μπορώ να πετύχω αυτό που θέλω..

Υπάρχει η συνάρτηση createMaskFromColor() της κλάσης QPixmap που δίνοντας της σαν παράμετρο το χρώμα δημιουργεί μια μάσκα (είναι η μαγκιά που ενδιάμεσα της βλέπεις τα πίσω παράθυρα και μπορείς να αλληλεπιδράσεις με αυτά) με βάση το χρώμα, δλδ όπου είναι ίδιο το χρώμα το κάνει διάφανο (ή όπου δεν είναι ίδιο το χρώμα, ορίζεται και αυτό με παράμετρο).

Το θέμα είναι ότι παρ όλα αυτά δεν έχω καταφέρει να το κάνω να δουλέψει ακόμα.. δεν ξέρω τι κάνω λάθος.. πρέπει να είναι προγραμματιστικό απ ότι καταλαβαίνω..

όποιος μπορεί ας ρίξει μια ματιά..

 

>#include <QtGui>

class MyWidget : public QWidget
{
public:
   MyWidget();

protected:
   void paintEvent(QPaintEvent *);
};


MyWidget::MyWidget()
{
}



void MyWidget::paintEvent(QPaintEvent *)
{
   QPixmap pix(size());
   QPainter painter(this);

   painter.setRenderHint(QPainter::Antialiasing);
   painter.setPen(Qt::darkGreen);
   painter.drawRect(40, 40, 200,200);
   painter.drawLine(20, 20, 300,300);
   painter.redirected(&pix);
   painter.drawLine(40, 40, 200,400);
   QRegion r2(pix.createMaskFromColor(Qt::darkGreen,Qt::MaskOutColor));
   setMask(r2);
}

int main(int argc, char *argv[])
{
   QApplication app(argc, argv);
   MyWidget w1;
   
   //w1.setWindowOpacity(0.8);
   w1.setMouseTracking(true);

   w1.setWindowFlags(Qt::WindowStaysOnTopHint);
   w1.showMaximized();

   return app.exec();
}

 

Για δοκίμασε setStyleSheet("background: transparent"); μήπως σε εξυπηρετήσει (στο Constructor).

Επίσης δες και το setAttribute(Qt::WA_TransparentForMouseEvents); (βλ. WA_TransparentForMouseEvents).

--

Ένα "painter.fillRect(rect(), Qt::transparent);" στο paint-event φαίνεται ότι δουλεύει σε S60 σχεδιάζοντας τα γραφικά κατευθείαν στο background του συστήματος. Λόγο όμως ότι τρέχω κάτω από S60 Simulator δυστυχώς δεν μπορώ να προτείνω κάτι περισσότερο διότι επεμβαίνει ο Simulator και έτσι δεν είναι δυνατόν να δω την συμπεριφορά του προγράμματος ως καθαρή Windows εφαρμογή (πολύ δε περισσότερο ως εφαρμογή που τρέχει σε Linux).

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

"painter.fillRect(rect(), Qt::transparent); " Όταν λες :

...σχεδιάζοντας τα γραφικά κατευθείαν στο background του συστήματος.

τι ακριβώς εννοείς..?

Βασικά σε εμένα δεν έκανε τίποτα αλλά ίσως κάνω κάτι άλλο λάθος..

αλλά βλέπωντας το καταλαβαίνω ότι γεμίζει όλο το κύριο παράθυρο με "χρώμα" διάφανο.. δλδ έπρεπε να φαίνονται τα πίσω παράθυρα μέσα απ αυτό.. σε εμένα δεν έκανε καμιά αλλαγή αλλά αν όντως κάνει αυτό μπορεί να γίνει και με το setWindowOpacity(<τιμή μικρότερη του 1>); το οποίο και δουλεύει.

 

το "setAttribute(Qt::WA_TransparentForMouseEvents);" δεν έκανε αυτό που υπόσχεται.. απ ότι διάβασα μάλλον ισχύει μόνο για παράθυρα της ίδιας εφαρμογής και όχι αν πίσω από το παράθυρο είναι ένα άλλο άσχετο με την εφαρμογή.

 

το "setAttribute(Qt::WA_TranslucentBackground);" που οδηγήθηκα ψάχνοντας πληροφορίες για τις εντολές που μου έδωσες είχε ενδιαφέρον αποτέλεσμα δείχνοντας μόνο τα σχήματα (δες screenshot) που σχεδίασα με διάφανο φόντο (πράγμα που είναι ότι ακριβώς θέλω αρκεί να πέρναγαν και τα κλίκ από πίσω)...

post-69920-129063124893_thumb.jpg

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

τι ακριβώς εννοείς..?

Βασικά σε εμένα δεν έκανε τίποτα αλλά ίσως κάνω κάτι άλλο λάθος..

Απλά επιτρέπει την σχεδίαση στο background του SYMBIAN δίχως να φαίνεται το QWidget background αλλά αν δεν δουλεύει σε Linux τότε το ξεχνάς (υπάρχουν διαφορές στην συμπεριφορά του Qt μεταξύ S60 και υπολογιστών -- δεν έπρεπε αλλά καθώς είναι η πρώτη έκδοση του Qt για S60 υπάρχουν bugs και ασυμβατότητες).

[..]το "setAttribute(Qt::WA_TranslucentBackground);" που οδηγήθηκα ψάχνοντας πληροφορίες για τις εντολές που μου έδωσες είχε ενδιαφέρον αποτέλεσμα δείχνοντας μόνο τα σχήματα (δες screenshot) που σχεδίασα με διάφανο φόντο (πράγμα που είναι ότι ακριβώς θέλω αρκεί να πέρναγαν και τα κλίκ από πίσω)...

 

Σύμφωνα με την κοινότητα υποστήριξης του Qt αρκεί μετά να ορίσεις "setAttribute(Qt::WA_TransparentForMouseEvents);" .

Οπότε όρισε το εκ νέου σε συνδυασμό και με το WA_TranslucentBackground φυσικά.

Τώρα αν δεν παίζει ούτε με αυτό τον συνδυασμό attributes ...

 

Για περισσότερα δες εδώ.

--

Επίσης δες και εδώ (σε αυτόν δεν δούλευε το Qt::WA_TransparentForMouseEvents οπότε το έκανε με άλλο τρικ σε Linux και νομίζω ότι περιγράφει αυτό που ζητάς).

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Επίσης δες και εδώ (σε αυτόν δεν δούλευε το Qt::WA_TransparentForMouseEvents οπότε το έκανε με άλλο τρικ σε Linux και νομίζω ότι περιγράφει αυτό που ζητάς).

 

Με πιάνεις αδιάβαστο.. δεν μπόρεσα να τρέξω τον κώδικα που δίνει αυτός... μάλλον φταίει που είμαι άσχετος με το Qt..:P

 

ωστόσο.. (υποθέτω με τα λίγα που μπόρεσα να καταλάβω από τον κώδικα αυτού μάλλον κάτι παρόμοιο σκεφτήκαμε..)

σκέφτηκα ότι μπορώ κάθε φορά να δημιουργώ μια mask τόσο μικρή ώστε να μην επηρεάζει τα σχήματα μου (εφόσον δεν θα φαίνονται εκεί που θα είναι η mask), και να της αλλάζω θέση ανάλογα με την κίνηση του ποντικιού ώστε πάντα να πέφτει ο κέρσορας στην "τρύπα" του παραθύρου και να μπορεί να πατήσει στα πίσω παράθυρα..

 

>    QRegion r1(rect()); //περιοχή που ορίζεται από  το μέγεθος όλου του παραθύρου
   QRegion r2(QRect(100,100,10,10)); //περιοχή που ορίζεται από 10,10 pixel στη θέση 100,100 του παραθύρου
   QRegion r3(r1.xored(r2)); //περιοχή που ορίζεται από το r1 χωρίς το r2 (XOR))
   setMask(r3);

 

η περιοχή αυτή θα αλλάζει θέση ανάλογα με τη θέση του ποντικιού και αν οριστεί και με μέγεθος ενός pixel ούτε καν θα φαίνεται..

από άποψη ταχύτητας και πόσο βαρύ θα είναι το πρόγραμμα θα ενημερώσω μόλις τα υλοποιήσω αυτά..

 

 

 

(στην εικόνα φαίνεται η κενή περιοχή εκεί που είναι ο κέρσορας καθώς διακόπτεται και η διαγώνια γραμμή)

post-69920-129063124906_thumb.jpg

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

αυτό είναι το πρόβλημα

 

να στείλεις τα κλίκ στον "κώδικα" που σχεδιάζει στο desktop "παράθυρο"

 

ή να "γράφει" η εφαρμογή σου σ' αυτό

 

όχι να σχεδιάζεις σε "τζάμι"

 

άσχετος !

 

.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

αυτό είναι το πρόβλημα

 

να στείλεις τα κλίκ στον "κώδικα" που σχεδιάζει στο desktop "παράθυρο"

 

ή να "γράφει" η εφαρμογή σου σ' αυτό

 

όχι να σχεδιάζεις σε "τζάμι"

 

άσχετος !

 

.

 

Το πρόβλημα ήταν να περνάνε τα κλίκ από την εφαρμογή με τα σχήματα στις πίσω εφαρμογές.. δλδ κάτι σαν τζάμι που έχει τα σχέδια και περνάνε μόνο τα κλικ από μεσα του..

 

τελικά έγινε λειτουργική η εφαρμογή.. έχω φτιάξει μόνο ένα δεξιό τοίχο..

Βάζω τον κώδικα μήπως κάποιος έχει πολύ χρόνο και δεν ξέρει τι να τον κάνει ώστε να τον βελτιώσει..

πχ.

- καλύτερος τρόπος υπολογισμού της ανακλώμενης ακτίνας

- προγραμματισμός άλλων "τοίχων" ίσως σε πίνακες και δεν ξέρω και γώ τι..

- ανεξαρτητοποίηση της ακτίνας από τους τοίχους ώστε να ανακλάται ΑΝ βρει τοίχο χωρίς να είναι απαραίτητος όπως τώρα

-διαγώνιοι τοίχοι (μπόινγκ....!)

-προσθήκη controls ίσως με συνδυασμούς πλήκτρων ώστε να αλλάζουν παράμετροι του προγράμματος κατά τη διάρκεια εκτέλεσης..

-οτιδήποτε άλλο που θα βελτιώσει την ταχύτητα κλπ

 

>#include <QtGui>
#include <QMouseEvent>
#include <stdio.h>
#include <QPainter>
#include <QBrush>
#include <QPen>
#include <QPaintEvent>
#include <QMouseEvent>
#include <QTimerEvent>

class MyWidget : public QWidget
{
public:
   MyWidget();

private:
   QPoint wallver1, wallver2, wallhor1;
   QRect raytocursor, cursortowall, raytowall, reflexray;
   int repainttimer;



protected:
   void paintEvent(QPaintEvent *);
   //void mouseMoveEvent(QMouseEvent *);
   void timerEvent(QTimerEvent *);
   //void mousePressEvent(QMouseEvent *);
   void keyPressEvent(QKeyEvent *);
};


MyWidget::MyWidget()
{
   repainttimer=30;
   //setAttribute(Qt::WA_TransparentForMouseEvents);
   //setAttribute(Qt::WA_TranslucentBackground);
   //QTimer *timer = new QTimer(this);
   //connect(timer, SIGNAL(timeout()), this,SLOT(timeevent()));
     startTimer(repainttimer);
//    QPalette palette(MyWidget::palette());
//    palette.setColor(backgroundRole(), Qt::transparent);
//     setPalette(palette);


   raytocursor.setRect(0, 0, 0, 0);
   cursortowall.setRect(0, 0, 0, 0);
   reflexray.setRect(0, 0, 0, 0);

}


void MyWidget::timerEvent(QTimerEvent *){

   if(mapFromGlobal(QCursor::pos()) != raytocursor.topLeft()){
       raytocursor.setBottomRight(mapFromGlobal(QCursor::pos()));
       cursortowall.setTopLeft(raytocursor.bottomRight());

       if(raytocursor.width()>0){
           cursortowall.setHeight((raytocursor.height()*cursortowall.width())/raytocursor.width());
       }

       raytowall.setTopLeft(raytocursor.topLeft());
       raytowall.setBottomRight(cursortowall.bottomRight());

       reflexray.setTopLeft(raytowall.bottomLeft());
       reflexray.setBottomRight(QPoint(raytowall.right(), raytowall.bottom() + raytowall.height()));

       update();
       //repaint();
   }
}


void MyWidget::keyPressEvent(QKeyEvent *keyevent){

   if(keyevent->key()==(Qt::Key_S)){
       raytocursor.setTopLeft(raytocursor.bottomRight());
   }

   if(keyevent->key()==(Qt::Key_W)){
       cursortowall.setRight(raytocursor.right());
   }

   if(keyevent->key()==(Qt::UpArrow)){
       if(repainttimer-10 > 0){
          repainttimer-=10;
       }
   }

   if(keyevent->key()==(Qt::DownArrow)){
       repainttimer+=10;
   }
}


void MyWidget::paintEvent(QPaintEvent *)
{
   QPainter painter(this);
   //painter.fillRect(rect(), Qt::blue);
   //painter.setRenderHint(QPainter::Antialiasing);
   painter.setPen(Qt::black);
   //painter.drawRect(40, 40, 200,200);
   //painter.drawText(rect(), "gdshfjhd", QTextOption(Qt::AlignCenter));

   painter.drawLine(raytocursor.topLeft(),raytocursor.bottomRight()); //aktina pros kersora
   //painter.drawLine(cursortowall.right(), rect().top(), cursortowall.right(), rect().bottom()); //toixos
   if(raytocursor.width()>0){
       painter.drawLine(cursortowall.topLeft(), cursortowall.bottomRight());  //apo kersora pros toixo
   }else if(raytocursor.width()==0){
       //painter.drawText(rect(), "dieresh me mhden..", QTextOption(Qt::AlignCenter));
   }else{
       //painter.drawLine(cursortowall.topLeft(), cursortowall.bottomRight());
   }
   painter.drawLine(reflexray.topRight(), reflexray.bottomLeft());

   QRegion r1(rect());
   QRegion r2(QRect(raytocursor.right()-10,raytocursor.bottom()-10,21,21));
   QRegion r3(r1.xored(r2));
   setMask(r3);
}

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();
}

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Εγώ μελετάω την Qt τον τελευταίο καιρό όταν έχω χρόνο και με ενδιαφέρει να δω ιδέες.

Αλλά δεν καταλαβαίνω που μπορεί να χρησιμεύσει κάτι σαν αυτό που έφτιαξες.

Πέραν της τεχνικής με την διαφάνεια (που κι' αυτή δεν έχει άμεση πρακτική χρησιμότητα),

μου φαίνεται παντελώς άχρηστο.

 

Πάντως, σε ότι αφορά το γεωμετρικό μέρος, γενίκευση των ανακλάσεων σε διαγώνιους τοίχους γίνεται με την διανυσματική σχέση που έδωσα.

Η δυσκολία είναι μόνον να βρεθεί το κάθετο διάνυσμα n της ευθείας (βλ. αναλυτική γεωμετρία).

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.


  • Δημιουργία νέου...