INFO702 - TPs
Loading...
Searching...
No Matches
objects.cpp
1/****************************************************************************
2** Author: J.-O. Lachaud, University Savoie Mont Blanc
3** (adapted from Qt colliding mices example)
4**
5** Copyright (C) 2015 The Qt Company Ltd.
6** Contact: http://www.qt.io/licensing/
7****************************************************************************/
8
9#include <cmath>
10#include <cassert>
11#include <cstdlib>
12#include <QGraphicsScene>
13#include <QRandomGenerator>
14#include <QPainter>
15#include <QStyleOption>
16#include "objects.hpp"
17
18//static const double Pi = 3.14159265358979323846264338327950288419717;
19//static double TwoPi = 2.0 * Pi;
20
21// Global variables for simplicity.
22LogicalScene* logical_scene = 0;
23
24double rand01() { return double( rand() ) / double( RAND_MAX ); }
25
26///////////////////////////////////////////////////////////////////////////////
27// class Disk
28///////////////////////////////////////////////////////////////////////////////
29
30Disk::Disk( qreal r, const MasterShape* master_shape )
31 : _r( r ), _master_shape( master_shape ) {}
32
33QPointF
34Disk::randomPoint() const
35{
36 QPointF p;
37 do {
38 p = QPointF( ( rand01() * 2.0 - 1.0 ),
39 ( rand01() * 2.0 - 1.0 ) );
40 } while ( ( p.x() * p.x() + p.y() * p.y() ) > 1.0 );
41 return p * _r;
42}
43
44bool
45Disk::isInside( const QPointF& p ) const
46{
47 return QPointF::dotProduct( p, p ) <= _r * _r;
48}
49
50QRectF
51Disk::boundingRect() const
52{
53 return QRectF( -_r, -_r, 2.0 *_r, 2.0 * _r );
54}
55
56void
57Disk::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
58{
59 painter->setBrush( _master_shape->currentColor() );
60 painter->drawEllipse( QPointF( 0.0, 0.0 ), _r, _r );
61}
62
63
64///////////////////////////////////////////////////////////////////////////////
65// class MasterShape
66///////////////////////////////////////////////////////////////////////////////
67
68MasterShape::MasterShape( QColor cok, QColor cko )
69 : _f( 0 ), _state( Ok ), _cok( cok ), _cko( cko )
70{
71}
72
73void
74MasterShape::setGraphicalShape( GraphicalShape* f )
75{
76 _f = f;
77 if ( _f != 0 ) _f->setParentItem( this );
78}
79
80QColor
81MasterShape::currentColor() const
82{
83 if ( _state == Ok ) return _cok;
84 else return _cko;
85}
86
87MasterShape::State
88MasterShape::currentState() const
89{
90 return _state;
91}
92
93void
94MasterShape::paint( QPainter *, const QStyleOptionGraphicsItem *, QWidget *)
95{
96 // nothing to do, Qt automatically calls paint of every QGraphicsItem
97}
98
99void
100MasterShape::advance(int step)
101{
102 if ( !step ) return;
103
104 // (I) Garde les objets dans la scene.
105 auto p = scenePos(); // pareil que pos si MasterShape est bien à la racine.
106 // pos() est dans les coordonnées parent et setPos aussi.
107 if ( p.x() < -SZ_BD ) {
108 auto point = parentItem() != 0
109 ? parentItem()->mapFromScene( QPointF( IMAGE_SIZE + SZ_BD - 1, p.y() ) )
110 : QPointF( IMAGE_SIZE + SZ_BD - 1, p.y() );
111 setPos(point);
112 } else if ( p.x() > IMAGE_SIZE + SZ_BD ) {
113 auto point = parentItem() != 0
114 ? parentItem()->mapFromScene( QPointF( -SZ_BD + 1, p.y() ) )
115 : QPointF( -SZ_BD + 1, p.y() );
116 setPos(point);
117 }
118 if ( p.y() < -SZ_BD ) {
119 auto point = parentItem() != 0 ?
120 parentItem()->mapFromScene( QPointF( p.x(), IMAGE_SIZE + SZ_BD - 1 ) )
121 : QPointF( p.x(), IMAGE_SIZE + SZ_BD - 1 );
122 setPos(point);
123 } else if ( p.y() > IMAGE_SIZE + SZ_BD ) {
124 auto point = parentItem() != 0
125 ? parentItem()->mapFromScene( QPointF( p.x(), -SZ_BD + 1 ) )
126 : QPointF( p.x(), -SZ_BD + 1 );
127 setPos(point);
128 }
129
130 // (II) regarde les intersections avec les autres objets.
131 if ( logical_scene->intersect( this ) )
132 _state = Collision;
133 else
134 _state = Ok;
135}
136
137QPointF
138MasterShape::randomPoint() const
139{
140 assert( _f != 0 );
141 return mapToParent( _f->randomPoint() );
142}
143
144bool
145MasterShape::isInside( const QPointF& p ) const
146{
147 assert( _f != 0 );
148 return _f->isInside( mapFromParent( p ) );
149}
150
151QRectF
152MasterShape::boundingRect() const
153{
154 assert( _f != 0 );
155 return mapRectToParent( _f->boundingRect() );
156}
157
158
159///////////////////////////////////////////////////////////////////////////////
160// class MasterShape
161///////////////////////////////////////////////////////////////////////////////
162
163Asteroid::Asteroid( QColor cok, QColor cko, double speed, double r )
164 : MasterShape( cok, cko ), _speed( speed )
165{
166 // This shape is very simple : just a disk.
167 Disk* d = new Disk( r, this );
168 // Tells the asteroid that it is composed of just a disk.
169 this->setGraphicalShape( d );
170}
171
172void
173Asteroid::advance(int step)
174{
175 if (!step) return;
176 setPos( mapToParent( _speed, 0.0 ) );
177 MasterShape::advance( step );
178}
179
180
181
182///////////////////////////////////////////////////////////////////////////////
183// class LogicalScene
184///////////////////////////////////////////////////////////////////////////////
185
187 : nb_tested( n ) {}
188
189bool
191{
192 for ( int i = 0; i < nb_tested; ++i )
193 {
194 if ( f2->isInside( f1->randomPoint() )
195 || f1->isInside( f2->randomPoint() ) )
196 return true;
197 }
198 return false;
199}
200
201bool
203{
204 for ( auto f : formes )
205 if ( ( f != f1 ) && intersect( f, f1 ) )
206 return true;
207 return false;
208}
209
A disk is a simple graphical shape.
Definition objects.hpp:75
Abstract class that describes a graphical object with additional methods for testing collisions.
Definition objects.hpp:24
A class to store master shapes and to test their possible collisions with a randomized algorithm.
Definition objects.hpp:89
bool intersect(MasterShape *f1, MasterShape *f2)
Definition objects.cpp:190
LogicalScene(int n)
Definition objects.cpp:186
Polymorphic class that represents the top class of any complex shape.
Definition objects.hpp:38