/*************************************************************************** * Copyright (C) 2008 by Peter Dahlberg * * pdahlberg@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "graphicsellipseitem.h" #include #include #include #include #include #include #include "simulscene.h" #include "probechargewidget.h" #include #include "constants.h" #include #include GraphicsEllipseItem::GraphicsEllipseItem() { //setFlag(ItemIsMovable); //setFlag(ItemIsSelectable); setFlag(ItemIsFocusable); //setCacheMode(QGraphicsItem::DeviceCoordinateCache); //startTimer(100); myProbeChargeWidget = new ProbeChargeWidget(0,0,this); currProbePath = new QList; speedListX = new QList; speedListY = new QList; elapsedTimeList= new QList; setupVars(); } void GraphicsEllipseItem::setupVars () { setMasse(9.10938188e-31); setCharge(-1.6e-19); setStartSpeedX(0); setStartSpeedY(0); setPos(0,0); setAdaptiveStepLength(0.01); setAdaptiveStepControl(true); } void GraphicsEllipseItem::resetProbe() { setupVars(); } void GraphicsEllipseItem::timerEvent ( QTimerEvent * event ) { static double vx; vx++; //moveBy(vx/20.0,vx/20.0*vx/20.0); } GraphicsEllipseItem::~GraphicsEllipseItem() { } void GraphicsEllipseItem::mousePressEvent ( QGraphicsSceneMouseEvent *event ) { //QGraphicsEllipseItem::mousePressEvent(event); } void GraphicsEllipseItem::handleSceneChange(const QList & /*region*/) { if (myScenePos != scenePos()) { myScenePos = scenePos(); emit ScenePosChanged(myScenePos); emit ScenePosXChanged(myScenePos.x()); emit ScenePosYChanged(myScenePos.y()); } } /*! \fn GraphicsEllipseItem::calculateProbePath() */ void GraphicsEllipseItem::calculateProbePath(QPointF startPoint) { double startSpeedX = getStartSpeedX(); double startSpeedY = getStartSpeedY(); SimulScene* myScene = dynamic_cast(scene()); //wenn noch zu keiner scene gehoerend abbruch if (myScene == 0) return; //parameter der scene in lokale variablen uebernehmen double timePerStep = myScene->getTimePerStep(); int steps = myScene->getSteps(); double meterPerPx = myScene->getMeterPerPx(); //listen leeren currProbePath->clear(); speedListX->clear(); speedListY->clear(); elapsedTimeList->clear(); //startwerte in die listen setzen currProbePath->append(startPoint); speedListX->append(startSpeedX); speedListY->append(startSpeedY); elapsedTimeList->append(0); //startpunkt in den Pfad setzen flightPath = QPainterPath(startPoint); for(int i = 1; i< steps;++i) { //Geschwindigkeit (gesamt) double combinedSpeed = sqrt( speedListX->at(i-1)*speedListX->at(i-1) + speedListY->at(i-1)*speedListY->at(i-1) ); double myMasse = getMasse(combinedSpeed); //qDebug()<< myMasse; double powerX = myScene->getPowerAt(currProbePath->at(i-1), charge, speedListX->at(i-1),speedListY->at(i-1), 'x'); double powerY = myScene->getPowerAt(currProbePath->at(i-1), charge, speedListX->at(i-1),speedListY->at(i-1), 'y'); //automatische Zeitschrittanpassung 0.008 if (isAdaptiveStepControlEnabled()&&combinedSpeed != 0) timePerStep = getAdaptiveStepLength()/(combinedSpeed/meterPerPx); //if (timePerStep < (1/10.0 * myScene->getTimePerStep())) timePerStep = 1/10.0 * myScene->getTimePerStep(); //if (timePerStep > (19.0/10.0 * myScene->getTimePerStep())) timePerStep = 19.0/10.0 * myScene->getTimePerStep(); double combinedPower = sqrt(powerX*powerX+powerY*powerY); if (isAdaptiveStepControlEnabled() && combinedPower !=0) { timePerStep = fabs((-combinedSpeed + sqrt(combinedSpeed*combinedSpeed + 2*(combinedPower/myMasse)*getAdaptiveStepLength()*meterPerPx)) / (combinedPower/myMasse)); } //qDebug()<at(i-1) + deltaSpeedX; double newspeedY = speedListY->at(i-1) + deltaSpeedY; double deltaDistX = (newspeedX * timePerStep); double deltaDistY = (newspeedY * timePerStep); //qDebug() << deltaDistY; //if (i >= 4) { // double dvx = (-9*speedListX->at(i-4)+37*speedListX->at(i-3)-59*speedListX->at(i-2)+55*speedListX->at(i-1))/24.0; // double dvy = (-9*speedListY->at(i-4)+37*speedListY->at(i-3)-59*speedListY->at(i-2)+55*speedListY->at(i-1))/24.0; //double dvx = (xp) / timePerStep ; //double dvy = (yp) / timePerStep ; // deltaDistX = timePerStep/24.0 *(speedListX->at(i-3)- 5*speedListX->at(i-2)+19*speedListX->at(i-1)+9*dvx); // deltaDistY = timePerStep/24.0 *(speedListY->at(i-3)- 5*speedListY->at(i-2)+19*speedListY->at(i-1)+9*dvy); //qDebug()<< deltaDistX<< " "<< deltaDistY; //} // double k1x = deltaDistX; // double k1y = deltaDistY; // QPointF k2point = QPointF(currProbePath->at(i-1).x() * meterPerPx + k1x/2.0,currProbePath->at(i-1).y()* meterPerPx + k1y/2.0); // double k2x = myScene->getPowerAt( k2point , charge, k1x/timePerStep,k1y/timePerStep, 'x') /myMasse * timePerStep/2.0 * timePerStep; // double k2y = myScene->getPowerAt( k2point , charge, k1x/timePerStep,k1y/timePerStep, 'y') /myMasse * timePerStep/2.0 * timePerStep; // QPointF k3point = QPointF(currProbePath->at(i-1).x()* meterPerPx + k2x/2.0,currProbePath->at(i-1).y()* meterPerPx + k2y/2.0); // double k3x = myScene->getPowerAt( k3point , charge, k2x/timePerStep,k2y/timePerStep, 'x') /myMasse * timePerStep/2.0 * timePerStep; // double k3y = myScene->getPowerAt( k3point , charge, k2x/timePerStep,k2y/timePerStep, 'y') /myMasse * timePerStep/2.0 * timePerStep; // QPointF k4point = QPointF(currProbePath->at(i-1).x() + k3x,currProbePath->at(i-1).y() + k3y); // double k4x = myScene->getPowerAt( k4point , charge, k3x/timePerStep,k3y/timePerStep, 'x') /myMasse * timePerStep * timePerStep; // double k4y = myScene->getPowerAt( k4point , charge, k3x/timePerStep,k3y/timePerStep, 'y') /myMasse * timePerStep * timePerStep; // // deltaDistX = (k1x +2*k2x+2*k3x+k4x)/6.0; // deltaDistY = (k1y +2*k2y+2*k3y+k4y)/6.0; QPointF newPoint(currProbePath->at(i-1).x() + deltaDistX/meterPerPx ,currProbePath->at(i-1).y() + deltaDistY/meterPerPx); //Scrollbar int Probleme vermeiden if (newPoint.x() + 10 > INT_MAX || newPoint.x() - 10 < INT_MIN) break; if (newPoint.y() + 10 > INT_MAX || newPoint.y() - 10 < INT_MIN) break; if (myScene->stopsHere(currProbePath->at(i-1),newPoint)) break; currProbePath->append(newPoint); speedListX->append(newspeedX); speedListY->append(newspeedY); elapsedTimeList->append(elapsedTimeList->at(i-1) + timePerStep); } int path_entry_step = currProbePath->count()/5000.0; //jeder entry_step(te) step wird eingetragen if (path_entry_step == 0) path_entry_step = 1; for (int i = 1; i< currProbePath->count();++i) { if (i%path_entry_step == 0 || i==currProbePath->count()) flightPath.lineTo(currProbePath->at(i)); } qDebug()<< "Probe Path: " <<*currProbePath; //qDebug()<< "speed x: "<<*speedListX; //qDebug()<< "speed y: "<<*speedListY; //qDebug()<at(12); //qDebug()<<"power x: "<< (double)myScene->getPowerAt(QPointF(0,0), charge, 'x'); //qDebug()<<"power y: " << (double)myScene->getPowerAt(QPointF(0,0), charge, 'y'); //qDebug()<< getMasse(5e+20); } QList *GraphicsEllipseItem::getElapsedTimeList() { return elapsedTimeList; } double GraphicsEllipseItem::getMasse(double speed) { //damit kein inf oder nan entsteht if(speed > (SPEED_OF_LIGHT - 3e-8)) speed = SPEED_OF_LIGHT - 3e-8; //fuer v>=c nehme v (etwas) * GraphicsEllipseItem::getCurrProbePath() { return currProbePath; } double GraphicsEllipseItem::getStartSpeedX() const { return startSpeedX; } void GraphicsEllipseItem::setStartSpeedX ( double theValue ) { if (startSpeedX == theValue) return; startSpeedX = theValue; emit startSpeedXChanged(theValue); } double GraphicsEllipseItem::getStartSpeedY() const { return startSpeedY; } void GraphicsEllipseItem::setStartSpeedY ( double theValue ) { if (startSpeedY == theValue) return; startSpeedY = theValue; emit startSpeedYChanged(theValue); } /*! \fn GraphicsEllipseItem::setScenePosY(double posY) */ void GraphicsEllipseItem::setScenePosY(double newPosY) { moveBy(0, newPosY - scenePos().y()); } /*! \fn GraphicsEllipseItem::setScenePosX(double posX) */ void GraphicsEllipseItem::setScenePosX(double newPosX) { moveBy(newPosX - scenePos().x(),0 ); } QPainterPath GraphicsEllipseItem::getFlightPath() const { return flightPath; } void GraphicsEllipseItem::setFlightPath ( const QPainterPath& theValue ) { if (flightPath==theValue) return; flightPath = theValue; } bool GraphicsEllipseItem::isAdaptiveStepControlEnabled() const { return adaptiveStepControlEnabled; } void GraphicsEllipseItem::setAdaptiveStepControl ( bool theValue ) { if (adaptiveStepControlEnabled == theValue) return; adaptiveStepControlEnabled = theValue; emit adaptiveStepControlChanged(theValue); } double GraphicsEllipseItem::getAdaptiveStepLength() const { return adaptiveStepLength; } void GraphicsEllipseItem::setAdaptiveStepLength ( double theValue ) { if (adaptiveStepLength == theValue) return; adaptiveStepLength = theValue; emit adaptiveStepLengthChanged(theValue); }