Как сделать так, чтобы метод родительского класса, нацеленный на работу с другими объектами этого же класса, работал и с объектами дочерних классов
Пишу программу на Qt, упрощенно моделирующую распространение болезни. Осуществляю столкновение окружностей на экране. При столкновении объектов родительского класса всё проходит хорошо. Но если добавить объекты дочернего класса, начинаются проблемы - дочерние объекты между собой не взаимодействуют. Так же, когда объект родительского класса врезается в объект дочернего происходит некорректное поведение. Видимо проблема в том, что я в определении метода collideWithCircle родительского класса делаю проверку на столкновение конкретно с классом Circle. Как сделать так, чтобы этот метод взаимодействовал со всеми дочерними классами Circle.
Родительский класс:
class Circle : public QObject, public QGraphicsItem
{
Q_OBJECT
public:
Circle(QTimer *parent);
~Circle();
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) ;
QPainterPath shape() const override;
QRectF boundingRect() const override;
int getNum() const;
void setSpeed(qreal speed);
qreal getRadius() const;
public slots:
void move();
//protected:
// void advance(int step);
//
private:
void collideWithCircle();
static int count;
int num;
qreal speed;
qreal radius;
qreal movingDirection;
};
Дочерний класс:
class Sick : public Circle
{
Q_OBJECT
public:
Sick(QTimer *timer);
~Sick();
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) ;
QPainterPath shape() const override;
QRectF boundingRect() const override;
};
Определение метода родительского класса:
void Circle::collideWithCircle()
{
QList<QGraphicsItem*> list = collidingItems();
for (int i = 0; i < list.size(); i++) {
if (typeid(*(list[i])) == typeid(Circle)){
Circle *targetCicrle = dynamic_cast<Circle*>(list[i]); // после проверки привожу элемент к типу Circle
// в случае перекрытия окружностей - перемещаем их вдоль прямой, соединяющей их центры
qreal circleDist = sqrt((x()-targetCicrle->x())*(x()-targetCicrle->x()) + (y()-targetCicrle->y())*(y()-targetCicrle->y())); // расстояние между центрами окружностей
qreal overlap = 0.5f * (2*radius - circleDist); //величина перекрытия (коэф. 0.5 т.к каждая окружность будет преодолевать расстояние перекрытия)
qreal dx = overlap * (this->x() - targetCicrle->x()) / circleDist;
qreal dy = overlap * (this->y() - targetCicrle->y()) / circleDist;
this->setPos(x() + dx, y() + dy);
qreal targetDx = overlap * (this->x() - targetCicrle->x()) / circleDist;
qreal targetDy = overlap * (this->y() - targetCicrle->y()) / circleDist;
targetCicrle->setPos(targetCicrle->x() - targetDx, targetCicrle->y() - targetDy);
// изменение направления движения окружностей в случае столкновения с другой окружностью
qreal middle;
if (list[i]->x() == this->x()) {
middle = 90.0;
//qDebug() << "!!!" << endl;
}
else middle = qRadiansToDegrees(atan((targetCicrle->y()-this->y())/(targetCicrle->x()-this->x())));
if (middle == 0) middle = 180;
qreal dD = this->movingDirection - middle;
this->movingDirection = (int)(-(middle/fabs(middle))*180 - dD + middle) % 360;
if (fabs(this->movingDirection) > 180) this->movingDirection = -((int)movingDirection % 180); // оставляю измерения угла в пределах [-180 ; 180]
}
// столкновение с созданными границами
else if (typeid(*list[i]) == typeid(Border)) {
Border *brd = dynamic_cast<Border*>(list[i]);
qreal borderDirect = brd->getDirection();
this->movingDirection = -(this->movingDirection-borderDirect)+borderDirect;
}
}
}