예제 #1
0
void
MissionSelector::startMission(unsigned num)
{
  Entry missionEntry;
  if(mCurrentCampaign == NULL) {
    // FIXME: we should fall back to station school in case a first timer plays
    missionEntry = mMissions[0];
  }
  else {
    if(num < 0 || num >= static_cast<int>(mCurrentMissions.size())) return;
    mMissionNum = num;
    missionEntry = mCurrentMissions[num];
  }
  
  Mission* oldMission = rMain()->getMission();
  
  Orbit* orbitScreen = static_cast<Orbit*>(rMain()->getScreenManager().getState(Main::ORBIT_SCREEN));
  orbitScreen->enterReadyState();
  
  DataFile* dataFile = new DataFile();
  Mission* mission = new Mission(dataFile);
  dataFile->setRootItem(mission);
  rMain()->setMission(mission);
  mission->initScriptFile(missionEntry.script);
  
  if(oldMission != NULL) {
    if (oldMission == ConfigManager::getPlayer()->getHomeBase()) {
      ConfigManager::getSingleton().savePlayer();
    }
    else {
      delete oldMission->getDataFile();
    }
  }
}
예제 #2
0
void
MissionSelector::loadMission(string fileName)
{
  if(fileName == "") return;

  Mission* oldMission = rMain()->getMission();
  
  Orbit* orbitScreen = static_cast<Orbit*>(rMain()->getScreenManager().getState(Main::ORBIT_SCREEN));
  orbitScreen->enterReadyState();
  
  DataFile* dataFile = new DataFile(stringToWString(fileName));

  if(dataFile->getRootItem() != NULL) {
    Mission* mission = dataFile->getRootItem()->castToClass<Mission>();
    if(mission != NULL) {
      rMain()->setMission(mission);      
  
      if(oldMission != NULL) {
        if (oldMission == ConfigManager::getPlayer()->getHomeBase()) {
          ConfigManager::getSingleton().savePlayer();
        }
        else {
          delete oldMission->getDataFile();
        }
      }
    }
  }
}
예제 #3
0
파일: solarsysxml.cpp 프로젝트: jpcoles/ZM
static bool createRotation(ParserContext* ctx, const xmlChar** att)
{
    double period = 0.0;
    double obliquity = 0.0;
    double axisLongitude = 0.0;
    double offset = 0.0;
    double epoch = astro::J2000;

    if (att != NULL)
    {
        for (int i = 0; att[i] != NULL; i += 2)
        {
            if (matchName(att[i], "period"))
            {
                if (matchName(att[i + 1], "sync"))
                    period = 0.0;
                else
                    parseTime(att[i + 1], period, "h");
            }
            else if (matchName(att[i], "obliquity"))
                parseAngle(att[i + 1], obliquity);
            else if (matchName(att[i], "axis-longitude"))
                parseAngle(att[i + 1], axisLongitude);
            else if (matchName(att[i], "offset"))
                parseAngle(att[i + 1], offset);
            else if (matchName(att[i], "epoch"))
                parseEpoch(att[i + 1], epoch);
        }
    }

    assert(ctx->body != NULL);

    RotationElements re;
    // A period of 0 means that the object is in synchronous rotation, so
    // we'll set its rotation period equal to its orbital period.  The catch
    // is that we require that the orbit was specified before the rotation
    // elements within the XML file.
    Orbit* orbit = ctx->body->getOrbit();
    if (orbit == NULL)
        return false;

    if (period == 0.0)
        re.period = (float) orbit->getPeriod();
    else
        re.period = (float) period / 24.0f;
    re.obliquity = (float) degToRad(obliquity);
    re.axisLongitude = (float) degToRad(axisLongitude);
    re.offset = (float) degToRad(offset);
    re.epoch = epoch;
    ctx->body->setRotationElements(re);
    
    return true;
}
예제 #4
0
void MixedOrbit::sample(double t0, double t1, int nSamples,
                        OrbitSampleProc& proc) const
{
    Orbit* o;
    if (t0 < begin)
        o = beforeApprox;
    else if (t0 < end)
        o = primary;
    else
        o = afterApprox;
    o->sample(t0, t1, nSamples, proc);
}
예제 #5
0
파일: Orbit.cpp 프로젝트: j-faria/Exoplanet
void Orbit::test()
{
	Orbit o;
	o.load("Orbits/orbits0.710.dat");

	vector<double> t;
	for(double tt=-10; tt <= 10; tt += 0.01)
		t.push_back(tt);

	vector<double> y = o.evaluate(t, 1.);
	for(size_t i=0; i<y.size(); i++)
		cout<<t[i]<<' '<<y[i]<<endl;
}
예제 #6
0
void SystemView::PutBody(const SystemBody *b, const vector3d &offset, const matrix4x4f &trans)
{
	if (b->type == SystemBody::TYPE_STARPORT_SURFACE) return;
	if (b->type != SystemBody::TYPE_GRAVPOINT) {

		if (!m_bodyIcon) {
			m_bodyIcon.reset(new Graphics::Drawables::Disk(m_renderer, Color::WHITE, 1.0f));
		}

		const double radius = b->GetRadius() * m_zoom;

		matrix4x4f invRot = trans;
		invRot.ClearToRotOnly();
		invRot = invRot.InverseOf();

		matrix4x4f bodyTrans = trans;
		bodyTrans.Translate(vector3f(offset));
		bodyTrans.Scale(radius);
		m_renderer->SetTransform(bodyTrans * invRot);
		m_bodyIcon->Draw(m_renderer);

		m_renderer->SetTransform(trans);

		PutLabel(b, offset);
	}

	Frame *frame = Pi::player->GetFrame();
	if(frame->IsRotFrame()) frame = frame->GetNonRotFrame();
	if(frame->GetSystemBody() == b && frame->GetSystemBody()->GetMass() > 0) {
		const double t0 = Pi::game->GetTime();
		Orbit playerOrbit = Pi::player->ComputeOrbit();
		PutOrbit(&playerOrbit, offset, Color::RED, b->GetRadius());
		PutSelectionBox(offset + playerOrbit.OrbitalPosAtTime(m_time - t0)* double(m_zoom), Color::RED);
	}

	if (b->children.size()) {
		for(std::vector<SystemBody*>::const_iterator kid = b->children.begin(); kid != b->children.end(); ++kid) {
			if (is_zero_general((*kid)->orbit.GetSemiMajorAxis())) continue;
			if ((*kid)->orbit.GetSemiMajorAxis() * m_zoom < ROUGH_SIZE_OF_TURD) {
				PutOrbit(&((*kid)->orbit), offset, Color(0, 255, 0, 255));
			}

			// not using current time yet
			vector3d pos = (*kid)->orbit.OrbitalPosAtTime(m_time);
			pos *= double(m_zoom);

			PutBody(*kid, offset + pos, trans);
		}
	}
}
예제 #7
0
파일: SystemView.cpp 프로젝트: tomm/pioneer
void TransferPlanner::AddStartTime(double timeStep) {
	if(std::fabs(m_startTime) < 1.)
		m_startTime = Pi::game->GetTime(); 

	m_startTime += m_factor * timeStep;
	double deltaT = m_startTime - Pi::game->GetTime();
	if(deltaT > 0.)
	{
		Frame *frame = Pi::player->GetFrame()->GetNonRotFrame();
		Orbit playerOrbit = Orbit::FromBodyState(Pi::player->GetPositionRelTo(frame), Pi::player->GetVelocityRelTo(frame), frame->GetSystemBody()->GetMass());

		m_position = playerOrbit.OrbitalPosAtTime(deltaT);
		m_velocity = playerOrbit.OrbitalVelocityAtTime(frame->GetSystemBody()->GetMass(), deltaT);
	}
	else
		ResetStartTime();
}
예제 #8
0
double Orbit::calcDeviance(Orbit &other)
{
	if ( !m_bValid ) return 0.0; 

	// special case: if one orbit's apogee is smaller than the other orbit's
	// perigee, the first orbit is completely contained within the second.
	if ( m_apogee < other.m_perigee )
	{
		// we are completely contained within other
		return other.m_orbitArea - m_orbitArea;
	}
	if ( other.m_apogee < m_perigee )
	{
		// other is completely contained within us
		return m_orbitArea - other.m_orbitArea;
	}

	// do a lap around and note the difference between the r values
	double thetaStep = TWOPI/1440.0; // one fourth of a degree per step. Arbitrarily chosen.

	double deviance = 0.0;
	for ( double theta=0.0 ; theta<TWOPI ; theta+=thetaStep )
	{
		// note the distances at this location
		double rThis = getR(theta);
		double rOther = other.getR(theta);

		// make them in to volumes. Each is a stepFraction chunk of a circle
		// good old r^2*dTheta/2
		double areaThis = rThis*rThis*thetaStep*0.5;
		double areaOther = rOther*rOther*thetaStep*0.5;
		double diff = fabs(areaThis - areaOther);
		deviance += diff;
	}

	return deviance;
}
예제 #9
0
void SolarSystemCreator::makeOrbit(Orbit& orbit)
{
    int d = SSGX::d6();

    if (d == 3)
        orbit.setEccentricity( (double)SSGX::dn(2000) / 10000.0);
    else
        orbit.setEccentricity( (double)SSGX::dn(200) / 10000.0);

    if (d == 4)
        orbit.setInclination( (double)(SSGX::d100() -50)/2.5);
    else
        orbit.setInclination( (double)(SSGX::d100() -50)/20);

    if (d == 6)
        orbit.setObliquity( (double)(SSGX::d100() -50)/2.5);
    else
        orbit.setObliquity( (double)(SSGX::d100() -50)/10);
}
예제 #10
0
static void CalculateOsculatingElements(const Orbit& orbit,
                                        double t,
                                        double dt,
                                        OrbitalElements* elements)
{
    double sdt = dt;

    // If the trajectory is finite, make sure we sample
    // it inside the valid time interval.
    if (!orbit.isPeriodic())
    {
        double beginTime = 0.0;
        double endTime = 0.0;
        orbit.getValidRange(beginTime, endTime);
        clog << "t+dt: " << t + dt << ", endTime: " << endTime << endl;
        if (t + dt > endTime)
        {
            clog << "REVERSE\n";
            sdt = -dt;
        }
    }

    Point3d p0 = orbit.positionAtTime(t);
    Point3d p1 = orbit.positionAtTime(t + sdt);
    Vec3d v0 = orbit.velocityAtTime(t);
    Vec3d v1 = orbit.velocityAtTime(t + sdt);

    double accel = ((v1 - v0) / sdt).length();
    Vec3d r = p0 - Point3d(0.0, 0.0, 0.0);
    double GM = accel * (r * r);

    clog << "vel: " << v0.length() / 86400.0 << endl;
    clog << "vel (est): " << (p1 - p0).length() / sdt / 86400 << endl;
    clog << "osc: " << t << ", " << dt << ", " << accel << ", GM=" << GM << endl;

    StateVectorToElements(p0, v0, GM, elements);
}
예제 #11
0
Planet SolarSystemCreator::createPlanet(
        double currentDistance,
        bool isSatellite,
        Planet& planetTop,
        double *prevDistance)
{
    Planet planet;

    Orbit orbit;
    int d = SSGX::d6();

    if (d == 3)
        orbit.setEccentricity( (double)SSGX::dn(1000) / 10000.0);
    else
        orbit.setEccentricity( (double)SSGX::dn(300) / 10000.0);

    if (d == 4)
        orbit.setInclination( (double)(SSGX::d100() -50)/30);
    else
        orbit.setInclination( (double)(SSGX::d100() -50)/5);

    if (d == 4)
        orbit.setObliquity( (double)(SSGX::d100() -50)/2);
    else
        orbit.setInclination( (double)(SSGX::d100() -50));

    d = SSGX::d6();

    if (currentDistance > _star->outerLifeZone()) {
        if (d < 5) {
            planet.setCoreType(NSPlanet::ctIcy);
            planet.setDensity( ((double)(SSGX::dn(400)))/1000*5520.0);
            if (!isSatellite)
                planet.setDiameter(SSGX::icyDiameter());
            else
                planet.setDiameter(SSGX::satDiameter());

        }
        else {
            if (!isSatellite)
                planet.setDiameter(SSGX::rockyDiameter());
            else
                planet.setDiameter(SSGX::satDiameter());

            planet.setDensity( ((double)(400+SSGX::dn(600)))/1000*5520.0);
        }
    }
    else {
        if (!isSatellite)
            planet.setDiameter(SSGX::rockyDiameter());
        else
            planet.setDiameter(SSGX::satDiameter());
        planet.setDensity( ((double)(400+SSGX::dn(900)))/1000*5520.0);
    }



    while (isSatellite && planet.diameter() > planetTop.diameter() / 3)
        planet.setDiameter(planet.diameter()/2);


    double dTemp = 255 / sqrt(( currentDistance / sqrt (_star->luminosity())));
    planet.setTemperature(dTemp);
    double dmmwr = (0.02783 * dTemp) / ( pow(planet.gravEarth(),2) );
    planet.setMmwr(dmmwr);
    if (dmmwr < 120)
        planet.setAtmosphere(atVeryThin);
    if (dmmwr < 80)
        planet.setAtmosphere(atThin);
    if (dmmwr < 40)
        planet.setAtmosphere(atStandard);
    if (dmmwr < 20)
        planet.setAtmosphere(atDense);
    if (dmmwr < 5) {
        if (planet.diameter() > 20000 )
            planet.setAtmosphere(atMassive);
        else
            planet.setAtmosphere(atDense);
    }

    this->setPlanetType(planet,currentDistance);

    if (!isSatellite) {
        this->setPlanetModifiers(planet);
        planet.setPlanetFlag();
    }
    else {
        planet.setSatelliteFlag();
        //qDebug() << "Satellite flag set: " << planet.isSatellite();
    }

    if (!isSatellite) {
        orbit.setDistance(currentDistance);
        orbit.setYear(_star->mass());
    }
    else {
        double sSatDist = *prevDistance;
        if (sSatDist <= 0)
            sSatDist = 35000+(double)((SSGX::dn(90)+30) * planet.diameter());
        else
            sSatDist += (double)((SSGX::dn(70)+10) * planet.diameter());
        *prevDistance = sSatDist;

        orbit.setDistance(sSatDist);  //in km

        double d1 = orbit.distance() / 40000.0;
        d1 = (pow(d1,3) * 793.64) / (planetTop.massEarth() + planet.massEarth());
        double dYear = sqrt(d1);

        orbit.setFixedYear(dYear);
    }

    planet.setOrbit(orbit);

    int w = rand() % 10;
    switch (w) {
    case 1:
        planet.setName(_onomastikon->fakeNomen());
        break;
    case 2:
        planet.setName(_onomastikon->fakeNomen());
        break;
    case 3:
        planet.setName(_onomastikon->nomen());
        break;
    case 4:
        planet.setName(_onomastikon->nomen());
        break;
    case 5:
        planet.setName(_onomastikon->sigla());
        break;
    default:
        planet.setName(_onomastikon->pseudoNomen());
        break;

    }


    return planet;
}
예제 #12
0
static bool CreateTimeline(Body* body,
                           PlanetarySystem* system,
                           Universe& universe,
                           Hash* planetData,
                           const string& path,
                           Disposition disposition,
                           BodyType bodyType)
{
    FrameTree* parentFrameTree = NULL;
    Selection parentObject = GetParentObject(system);
    bool orbitsPlanet = false;
    if (parentObject.body())
    {
        parentFrameTree = parentObject.body()->getOrCreateFrameTree();
        orbitsPlanet = true;
    }
    else if (parentObject.star())
    {
        SolarSystem* solarSystem = universe.getSolarSystem(parentObject.star());
        if (solarSystem == NULL)
            solarSystem = universe.createSolarSystem(parentObject.star());
        parentFrameTree = solarSystem->getFrameTree();
    }
    else
    {
        // Bad orbit barycenter specified
        return false;
    }

    ReferenceFrame* defaultOrbitFrame = NULL;
    ReferenceFrame* defaultBodyFrame = NULL;
    if (bodyType == SurfaceObject)
    {
        defaultOrbitFrame = new BodyFixedFrame(parentObject, parentObject);
        defaultBodyFrame = CreateTopocentricFrame(parentObject, parentObject, Selection(body));
        defaultOrbitFrame->addRef();
        defaultBodyFrame->addRef();
    }
    else
    {
        defaultOrbitFrame = parentFrameTree->getDefaultReferenceFrame();
        defaultBodyFrame = parentFrameTree->getDefaultReferenceFrame();
    }
    
    // If there's an explicit timeline definition, parse that. Otherwise, we'll do
    // things the old way.
    Value* value = planetData->getValue("Timeline");
    if (value != NULL)
    {
        if (value->getType() != Value::ArrayType)
        {
            clog << "Error: Timeline must be an array\n";
            return false;
        }

        Timeline* timeline = CreateTimelineFromArray(body, universe, value->getArray(), path,
                                                     defaultOrbitFrame, defaultBodyFrame);
        if (timeline == NULL)
        {
            return false;
        }
        else
        {
            body->setTimeline(timeline);
            return true;
        }
    }

    // Information required for the object timeline.
    ReferenceFrame* orbitFrame   = NULL;
    ReferenceFrame* bodyFrame    = NULL;
    Orbit* orbit                 = NULL;
    RotationModel* rotationModel = NULL;
    double beginning             = -numeric_limits<double>::infinity();
    double ending                =  numeric_limits<double>::infinity();

    // If any new timeline values are specified, we need to overrideOldTimeline will
    // be set to true.
    bool overrideOldTimeline = false;

    // The interaction of Modify with timelines is slightly complicated. If the timeline
    // is specified by putting the OrbitFrame, Orbit, BodyFrame, or RotationModel directly
    // in the object definition (i.e. not inside a Timeline structure), it will completely
    // replace the previous timeline if it contained more than one phase. Otherwise, the
    // properties of the single phase will be modified individually, for compatibility with
    // Celestia versions 1.5.0 and earlier.
    if (disposition == ModifyObject)
    {
        const Timeline* timeline = body->getTimeline();
        if (timeline->phaseCount() == 1)
        {
            const TimelinePhase* phase = timeline->getPhase(0);
            orbitFrame    = phase->orbitFrame();
            bodyFrame     = phase->bodyFrame();
            orbit         = phase->orbit();
            rotationModel = phase->rotationModel();
            beginning     = phase->startTime();
            ending        = phase->endTime();
        }
    }

    // Get the object's orbit reference frame.
    bool newOrbitFrame = false;
    Value* frameValue = planetData->getValue("OrbitFrame");
    if (frameValue != NULL)
    {
        ReferenceFrame* frame = CreateReferenceFrame(universe, frameValue, parentObject, body);
        if (frame != NULL)
        {
            orbitFrame = frame;
            newOrbitFrame = true;
            overrideOldTimeline = true;
        }
    }

    // Get the object's body frame.
    bool newBodyFrame = false;
    Value* bodyFrameValue = planetData->getValue("BodyFrame");
    if (bodyFrameValue != NULL)
    {
        ReferenceFrame* frame = CreateReferenceFrame(universe, bodyFrameValue, parentObject, body);
        if (frame != NULL)
        {
            bodyFrame = frame;
            newBodyFrame = true;
            overrideOldTimeline = true;
        }
    }

    // If no orbit or body frame was specified, use the default ones
    if (orbitFrame == NULL)
        orbitFrame = defaultOrbitFrame;
    if (bodyFrame == NULL)
        bodyFrame = defaultBodyFrame;

    // If the center of the is a star, orbital element units are
    // in AU; otherwise, use kilometers.
    if (orbitFrame->getCenter().star() != NULL)
        orbitsPlanet = false;
    else
        orbitsPlanet = true;

    Orbit* newOrbit = CreateOrbit(orbitFrame->getCenter(), planetData, path, !orbitsPlanet);
    if (newOrbit == NULL && orbit == NULL)
    {
        if (body->getTimeline() && disposition == ModifyObject)
        {
            // The object definition is modifying an existing object with a multiple phase
            // timeline, but no orbit definition was given. This can happen for completely
            // sensible reasons, such a Modify definition that just changes visual properties.
            // Or, the definition may try to change other timeline phase properties such as
            // the orbit frame, but without providing an orbit. In both cases, we'll just
            // leave the original timeline alone.
            return true;
        }
        else
        {
            clog << "No valid orbit specified for object '" << body->getName() << "'. Skipping.\n";
            return false;
        }
    }

    // If a new orbit was given, override any old orbit
    if (newOrbit != NULL)
    {
        orbit = newOrbit;
        overrideOldTimeline = true;
    }

    // Get the rotation model for this body
    double syncRotationPeriod = orbit->getPeriod();
    RotationModel* newRotationModel = CreateRotationModel(planetData, path, syncRotationPeriod);

    // If a new rotation model was given, override the old one
    if (newRotationModel != NULL)
    {
        rotationModel = newRotationModel;
        overrideOldTimeline = true;
    }

    // If there was no rotation model specified, nor a previous rotation model to
    // override, create the default one.
    if (rotationModel == NULL)
    {
        // If no rotation model is provided, use a default rotation model--
        // a uniform rotation that's synchronous with the orbit (appropriate
        // for nearly all natural satellites in the solar system.)
        rotationModel = CreateDefaultRotationModel(syncRotationPeriod);
    }
    
    if (ParseDate(planetData, "Beginning", beginning))
        overrideOldTimeline = true;
    if (ParseDate(planetData, "Ending", ending))
        overrideOldTimeline = true;

    // Something went wrong if the disposition isn't modify and no timeline
    // is to be created.
    assert(disposition == ModifyObject || overrideOldTimeline);

    if (overrideOldTimeline)
    {
        if (beginning >= ending)
        {
            clog << "Beginning time must be before Ending time.\n";
            return false;
        }

        // We finally have an orbit, rotation model, frames, and time range. Create
        // the object timeline.
        TimelinePhase* phase = TimelinePhase::CreateTimelinePhase(universe,
                                                                  body,
                                                                  beginning, ending,
                                                                  *orbitFrame,
                                                                  *orbit,
                                                                  *bodyFrame,
                                                                  *rotationModel);

        // We've already checked that beginning < ending; nothing else should go
        // wrong during the creation of a TimelinePhase.
        assert(phase != NULL);
        if (phase == NULL)
        {
            clog << "Internal error creating TimelinePhase.\n";
            return false;
        }

        Timeline* timeline = new Timeline();
        timeline->appendPhase(phase);

        body->setTimeline(timeline);

        // Check for circular references in frames; this can only be done once the timeline
        // has actually been set.
        // TIMELINE-TODO: This check is not comprehensive; it won't find recursion in
        // multiphase timelines.
        if (newOrbitFrame && isFrameCircular(*body->getOrbitFrame(0.0), ReferenceFrame::PositionFrame))
        {
            clog << "Orbit frame for " << body->getName() << " is nested too deep (probably circular)\n";
            return false;
        }

        if (newBodyFrame && isFrameCircular(*body->getBodyFrame(0.0), ReferenceFrame::OrientationFrame))
        {
            clog << "Body frame for " << body->getName() << " is nested too deep (probably circular)\n";
            return false;
        }
    }

    return true;
}
예제 #13
0
TimelinePhase* CreateTimelinePhase(Body* body,
                                   Universe& universe,
                                   Hash* phaseData,
                                   const string& path,
                                   ReferenceFrame* defaultOrbitFrame,
                                   ReferenceFrame* defaultBodyFrame,
                                   bool isFirstPhase,
                                   bool isLastPhase,
                                   double previousPhaseEnd)
{
    double beginning = previousPhaseEnd;
    double ending = numeric_limits<double>::infinity();

    // Beginning is optional for the first phase of a timeline, and not
    // allowed for the other phases, where beginning is always the ending
    // of the previous phase.
    bool hasBeginning = ParseDate(phaseData, "Beginning", beginning);
    if (!isFirstPhase && hasBeginning)
    {
        clog << "Error: Beginning can only be specified for initial phase of timeline.\n";
        return NULL;
    }

    // Ending is required for all phases except for the final one.
    bool hasEnding = ParseDate(phaseData, "Ending", ending);
    if (!isLastPhase && !hasEnding)
    {
        clog << "Error: Ending is required for all timeline phases other than the final one.\n";
        return NULL;
    }

    // Get the orbit reference frame.
    ReferenceFrame* orbitFrame;
    Value* frameValue = phaseData->getValue("OrbitFrame");
    if (frameValue != NULL)
    {
        orbitFrame = CreateReferenceFrame(universe, frameValue, defaultOrbitFrame->getCenter(), body);
        if (orbitFrame == NULL)
        {
            return NULL;
        }
    }
    else
    {
        // No orbit frame specified; use the default frame.
        orbitFrame = defaultOrbitFrame;
    }
    orbitFrame->addRef();

    // Get the body reference frame
    ReferenceFrame* bodyFrame;
    Value* bodyFrameValue = phaseData->getValue("BodyFrame");
    if (bodyFrameValue != NULL)
    {
        bodyFrame = CreateReferenceFrame(universe, bodyFrameValue, defaultBodyFrame->getCenter(), body);
        if (bodyFrame == NULL)
        {
            orbitFrame->release();
            return NULL;
        }
    }
    else
    {
        // No body frame specified; use the default frame.
        bodyFrame = defaultBodyFrame;
    }
    bodyFrame->addRef();

    // Use planet units (AU for semimajor axis) if the center of the orbit 
    // reference frame is a star.
    bool usePlanetUnits = orbitFrame->getCenter().star() != NULL;

    // Get the orbit
    Orbit* orbit = CreateOrbit(orbitFrame->getCenter(), phaseData, path, usePlanetUnits);
    if (!orbit)
    {
        clog << "Error: missing orbit in timeline phase.\n";
        bodyFrame->release();
        orbitFrame->release();
        return NULL;
    }

    // Get the rotation model
    // TIMELINE-TODO: default rotation model is UniformRotation with a period
    // equal to the orbital period. Should we do something else?
    RotationModel* rotationModel = CreateRotationModel(phaseData, path, orbit->getPeriod());
    if (!rotationModel)
    {
        // TODO: Should distinguish between a missing rotation model (where it's
        // appropriate to use a default one) and a bad rotation model (where
        // we should report an error.)
        rotationModel = new ConstantOrientation(Quaterniond::Identity());
    }

    TimelinePhase* phase = TimelinePhase::CreateTimelinePhase(universe,
                                                              body,
                                                              beginning, ending,
                                                              *orbitFrame,
                                                              *orbit,
                                                              *bodyFrame,
                                                              *rotationModel);

    // Frame ownership transfered to phase; release local references
    orbitFrame->release();
    bodyFrame->release();

    return phase;
}
예제 #14
0
파일: Sync.cpp 프로젝트: ADSWNJ/BaseSyncMFD
// ==============================================================================================================================================
//
bool SyncMFD::InterpolateClosestPassage(OBJHANDLE ref, Orbit *src, double lon,double lat,double orbit,double *diff,double *tim,double *head,double *tr)
{
	VECTOR3 Rot,Off;
	Orbit LEO;
	int i;
	double obli = 0.0;
	double trans = 0.0;
	double per = 0.0;
	double offset = 0.0;
	double size = 0.0;
	double time = 0.0;

	// Rotation elements
	obli   = oapiGetPlanetObliquity(ref);
	trans  = oapiGetPlanetTheta(ref);
	per    = oapiGetPlanetPeriod(ref);
	offset = oapiGetPlanetCurrentRotation(ref);
	size   = oapiGetSize(ref);

	LEO.LEO(ref);

	double step  = PI2/16.01;
	double start = orbit;
	double end   = orbit+PI2+(step/2.0);
	double trl, dst2;
	double dot,old_dot=0;


	VECTOR3 pos = _V(0,0,0);
	VECTOR3 vel = _V(0,0,0);
	VECTOR3 gpv = _V(0,0,0);
	VECTOR3 spd = _V(0,0,0);
	VECTOR3 relv = _V(0,0,0);
	VECTOR3 relp = _V(0,0,0);

	bool no_intercept=true;
	bool first=true;

	for (trl=start;trl<end;trl+=step) {

		// Caluclate time to a location
		time=Trl2Time(trl,src)/86400.0;

		// Caluclate Planets Rotation offset at that time
		PlanetAxis(obli,trans,offset,per,time,&Rot,&Off);

		// Calculate Ship's position vector and distance^2
		pos  = src->Position(trl);
		dst2 = dotp(pos,pos);

		// Reset the distance to correspond a surface position.
		pos  = set_length(pos,size);

		// Compute ship's surface velocity vector direction
		vel = crossp(src->norv,pos);

		// Compute ship's surface velocity vector magnitude
		vel = set_length(vel,src->ang*size/dst2);

		// Compute base's position vector
		gpv = VectorByLonLat(Rot,Off,lon,lat)*size;

		// Compute speed of the base
		spd = GroundSpeedVector(ref,time,lon,lat);

		// Copmute relative position to the base
		relv = (vel-spd);
		relp = (pos-gpv);

		dot = dotp(relv,relp);

		if (old_dot<0 && dot>0 && !first) {
			if (angle(pos,gpv)<PI05) {
				start=trl-step;
				no_intercept=false;
				break;
			}
		}

		first=false;
		old_dot=dot;
	}


    // Return N/A if no passage points found
	if (no_intercept) {
		if (head) *head = 0;
		if (diff) *diff = 0;
		if (tim)  *tim  = 0;
		if (tr)   *tr   = start+PI2-PI05;
		return false;
	}


	trl=start;
	old_dot=-1; // We are approaching the base
	double trll=0;
	no_intercept=true;

	for (i=0;i<24;i++) {

		step/=2.0;

		// Caluclate time to a location
		time=Trl2Time(trl,src)/86400.0;

		// Caluclate Planets Rotation offset at that time
		PlanetAxis(obli,trans,offset,per,time,&Rot,&Off);

		// Calculate Ship's position vector and distance^2
		pos  = src->Position(trl);
		dst2 = dotp(pos,pos);

		// Reset the distance to correspond a surface position.
		pos  = set_length(pos,size);

		// Compute ship's surface velocity vector direction
		vel = crossp(src->norv,pos);

		// Compute ship's surface velocity vector magnitude
		vel = set_length(vel,src->ang*size/dst2);

		// Compute base's position vector
		gpv = VectorByLonLat(Rot,Off,lon,lat)*size;

		// Compute speed of the base
		spd = GroundSpeedVector(ref,time,lon,lat);

		// Copmute relative position to the base
		relv = (vel-spd);
		relp = (pos-gpv);

		dot = dotp(relv,relp);

		trll=trl;
		if (dot==0) {
			 no_intercept=false;
			 break; // closest position archived, break
		}

		if (dot>0) { // base is behind of us, step back
			trl=trl-step;
			no_intercept=false;  // Verify, We have a base passage.
		}
		else trl=trl+step;	// base is front of us, cuntinue stepping
	}


	double dif=angle(pos, gpv);

	VECTOR3 zero=crossp(pos,spd);

	if (head) *head = nangle(relp,zero,pos);
	if (diff) *diff = dif;
	if (tim)  *tim  = time*86400.0;
	if (tr)   *tr   = trll;

	return true;
}
예제 #15
0
파일: SystemView.cpp 프로젝트: tomm/pioneer
void SystemView::PutBody(const SystemBody *b, const vector3d &offset, const matrix4x4f &trans)
{
	if (b->GetType() == SystemBody::TYPE_STARPORT_SURFACE) 
		return;

	if (b->GetType() != SystemBody::TYPE_GRAVPOINT)
	{
		if (!m_bodyIcon) 
		{
			Graphics::RenderStateDesc rsd;
			auto solidState = m_renderer->CreateRenderState(rsd);
			m_bodyIcon.reset(new Graphics::Drawables::Disk(m_renderer, solidState, Color::WHITE, 1.0f));
		}

		const double radius = b->GetRadius() * m_zoom;

		matrix4x4f invRot = trans;
		invRot.ClearToRotOnly();
		invRot = invRot.Inverse();

		matrix4x4f bodyTrans = trans;
		bodyTrans.Translate(vector3f(offset));
		bodyTrans.Scale(radius);
		m_renderer->SetTransform(bodyTrans * invRot);
		m_bodyIcon->Draw(m_renderer);

		m_renderer->SetTransform(trans);

		PutLabel(b, offset);
	}

	Frame *frame = Pi::player->GetFrame();
	if(frame->IsRotFrame()) 
		frame = frame->GetNonRotFrame();

	// display the players orbit(?)
	if(frame->GetSystemBody() == b && frame->GetSystemBody()->GetMass() > 0) 
	{
		const double t0 = m_game->GetTime();
		Orbit playerOrbit = Pi::player->ComputeOrbit();

		PutOrbit(&playerOrbit, offset, Color::RED, b->GetRadius());

		const double plannerStartTime = m_planner->GetStartTime();
		if(!m_planner->GetPosition().ExactlyEqual(vector3d(0,0,0))) 
		{
			Orbit plannedOrbit = Orbit::FromBodyState(m_planner->GetPosition(),
								  m_planner->GetVel(),
								  frame->GetSystemBody()->GetMass());
			PutOrbit(&plannedOrbit, offset, Color::STEELBLUE, b->GetRadius());
			if(std::fabs(m_time - t0) > 1. && (m_time - plannerStartTime) > 0.)
				PutSelectionBox(offset + plannedOrbit.OrbitalPosAtTime(m_time - plannerStartTime) * static_cast<double>(m_zoom), Color::STEELBLUE);
			else
				PutSelectionBox(offset + m_planner->GetPosition() * static_cast<double>(m_zoom), Color::STEELBLUE);
				
		}

		PutSelectionBox(offset + playerOrbit.OrbitalPosAtTime(m_time - t0)* double(m_zoom), Color::RED);
	}

	// display all child bodies and their orbits
	if (b->HasChildren()) 
	{
		for(const SystemBody* kid : b->GetChildren()) 
		{
			if (is_zero_general(kid->GetOrbit().GetSemiMajorAxis())) 
				continue;

			const double axisZoom = kid->GetOrbit().GetSemiMajorAxis() * m_zoom;
			if (axisZoom < DEFAULT_VIEW_DISTANCE)
			{
				const SystemBody::BodySuperType bst = kid->GetSuperType();
				const bool showLagrange = (bst == SystemBody::SUPERTYPE_ROCKY_PLANET || bst == SystemBody::SUPERTYPE_GAS_GIANT);
				PutOrbit(&(kid->GetOrbit()), offset, Color::GREEN, 0.0, showLagrange);
			}

			// not using current time yet
			const vector3d pos = kid->GetOrbit().OrbitalPosAtTime(m_time) * double(m_zoom);
			PutBody(kid, offset + pos, trans);
		}
	}
}
예제 #16
0
Planet SolarSystemCreator::createPlanet(
        double currentDistance,
        bool isSatellite,
        Planet& planetTop,
        double *prevDistance)
{
    Planet planet;
    if (isSatellite)
        planet.setParent(&planetTop);

    Orbit orbit;

    makeOrbit(orbit);
    makeDiameterAndDensity(isSatellite, planet, currentDistance, planetTop);


    double dTemp = 255 / sqrt(( currentDistance / sqrt (_star->luminosity())));
    planet.setTemperature(dTemp);
    double dmmwr = (0.02783 * dTemp) / ( pow(planet.gravEarth(),2) );
    planet.setMmwr(dmmwr);
    if (dmmwr < 120)
        planet.setAtmosphere(atVeryThin);
    if (dmmwr < 80)
        planet.setAtmosphere(atThin);
    if (dmmwr < 40)
        planet.setAtmosphere(atStandard);
    if (dmmwr < 20)
        planet.setAtmosphere(atDense);
    if (dmmwr < 5) {
        if (planet.diameter() > 20000 )
            planet.setAtmosphere(atMassive);
        else
            planet.setAtmosphere(atDense);
    }

    this->setPlanetType(planet,currentDistance);

    if (!isSatellite) {
        this->setPlanetModifiers(planet);
        planet.setPlanetFlag();
    }
    else {
        planet.setSatelliteFlag();
        //qDebug() << "Satellite flag set: " << planet.isSatellite();
    }

    if (!isSatellite) {
        orbit.setDistance(currentDistance);
        orbit.setYear(_star->mass());
    }
    else {
        double sSatDist = *prevDistance;
        if (sSatDist <= 0)
            if (planetTop.planetType() != ptGasGiant)
                sSatDist = 105000+(double)((SSGX::dn(20)+10) * planetTop.diameter());
            else
                sSatDist = 105000+(double)((SSGX::floatRand()*1.8+2.0) * planetTop.diameter());
        else
            sSatDist += 80000.0+(double)((SSGX::dn(50)+25) * planet.diameter());
        *prevDistance = sSatDist;

        orbit.setDistance(sSatDist);  //in km

        double d1 = orbit.distance() / 40000.0;
        d1 = (pow(d1,3) * 793.64) / (planetTop.massEarth() + planet.massEarth());
        double dYear = sqrt(d1);

        orbit.setFixedYear(dYear);
    }

    planet.setOrbit(orbit);

    int w = rand() % 10;
    switch (w) {
    case 1:
        planet.setName(_onomastikon->fakeNomen());
        break;
    case 2:
        planet.setName(_onomastikon->fakeNomen());
        break;
    case 3:
        planet.setName(_onomastikon->nomen());
        break;
    case 4:
        planet.setName(_onomastikon->nomen());
        break;
    case 5:
        planet.setName(_onomastikon->sigla());
        break;
    default:
        planet.setName(_onomastikon->pseudoNomen());
        break;

    }


    return planet;
}
예제 #17
0
int main()
{
    using namespace std;

    //This is the maximum error allowed when keplers_eqn() is used to solve for the
    //orbit's eccentric anomaly E. Shrink this number to increase numerical accuracy.
    double max_error = 1.0e-15;

    //Solve Kepler's equation N times. 
    int N = 10000000;

    //Save a subset of the N solutions, for plotting and testing purposes.
    int Nsave = 100000;

    //The remaining quanties used below.
    double* e = new double[N];
    double* M = new double[N];
    double* E = new double[N];
    int* iterations = new int[N];
    double x, xtime_sec, rn;
    clock_t t0, t1;
    double pi = Orbit().get_pi();
    Orbit orb;

    //Solve kepler's equation N times. Each orbit is randomly generated with
    //mean anomly M uniformly distributed between -Pi<M<Pi and eccentricity
    //logarithmically distributed so that log10(x) is uniformly distributed over
    //-6<log10(x)<0 where x=1-e so that e ranges over 10^(-6)<e<0.999999.
    srand(1);
    t0 = clock();
    for (int i=0; i<N; i++){

        //Get random number between 0<rn<1, calculate x=1-e and e=1-x.
        rn = (double)rand()/(double)RAND_MAX;
        x = pow(10.0, -6.0*rn);
        e[i] = 1.0 - x;

        //Random mean anomaly M.
        rn = (double)rand()/(double)RAND_MAX;
        M[i] = pi*(2.0*rn - 1.0);

        //Construct the orbit.
        orb = Orbit(1.0, e[i], 0.0, 0.0, 0.0, M[i]);

        //Calculate eccentric anomaly and track number of iterations used by keplers_eqn().
        E[i] = orb.keplers_eqn(max_error);
        iterations[i] = orb.i_ke;
    }
    //Execution time consumed by the main loop.
    t1 = clock();
    xtime_sec = (double)(t1 - t0)/CLOCKS_PER_SEC;
    cout << "execution time (sec) = " << xtime_sec << endl;

    //Store Nsave results in file keplers_eqn.dat.
    ofstream out("keplers_eqn.dat", ios::binary);
    out.write((char *)&xtime_sec, sizeof(xtime_sec));
    out.write((char *)&Nsave, sizeof(Nsave));
    out.write((char *)e, sizeof(e)*Nsave);
    out.write((char *)M, sizeof(M)*Nsave);
    out.write((char *)E, sizeof(E)*Nsave);
    out.write((char *)iterations, sizeof(iterations)*Nsave);
    out.close();

    //Delete large arrays.
    delete[] e;
    delete[] E;
    delete[] M;
}