Skip to content

Commit

Permalink
orbitalkiller: fixed wrong travel time calculation for cw orbits, min…
Browse files Browse the repository at this point in the history
…or optimizations
  • Loading branch information
Andrey Borunov committed Jun 6, 2016
1 parent e3faa8a commit 0916162
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 39 deletions.
Expand Up @@ -264,17 +264,20 @@ object OrbitalKiller extends ScageScreenAppDMT("Orbital Killer", property("scree
//val ship_start_position = earth.coord + DVec(-100, earth.radius + 199000)
//val ship_init_velocity = satelliteSpeed(ship_start_position, earth.coord, earth.linearVelocity, earth.mass, G, counterclockwise = true)/** 1.15 */

val ship_start_position = earth.coord + DVec(-100, earth.radius + 199015)
val ship_init_velocity = satelliteSpeed(ship_start_position, earth.coord, earth.linearVelocity, earth.mass, G, counterclockwise = true)/** 1.15 */
//val ship_start_position = earth.coord + DVec(-100, earth.radius + 198000)
//val ship_init_velocity = speedToHaveOrbitWithParams(ship_start_position, 900000, earth.coord, earth.linearVelocity, earth.mass, G, ccw = false)

//val ship_start_position = earth.coord + DVec(-100, earth.radius + 199015)
//val ship_init_velocity = satelliteSpeed(ship_start_position, earth.coord, earth.linearVelocity, earth.mass, G, counterclockwise = true)/** 1.15 */

// стоим на поверхности Луны
//val ship_start_position = moon.coord + DVec(500, moon.radius + 3.5)
//val ship_init_velocity = moon.linearVelocity + (ship_start_position - moon.coord).p*moon.groundSpeedMsec/*DVec.zero*//*satelliteSpeed(ship_start_position, earth.coord, earth.linearVelocity, earth.mass, G, counterclockwise = true)*1.15*/
//val ship_init_velocity = -escapeVelocity(ship_start_position, earth.coord, earth.linearVelocity, earth.mass, G, counterclockwise = true)*1.01

// на орбите в 1000 км от поверхности Луны
//val ship_start_position = moon.coord + DVec(0, moon.radius + 1000000)
//val ship_init_velocity = satelliteSpeed(ship_start_position, moon.coord, moon.linearVelocity, moon.mass, G, counterclockwise = true)
val ship_start_position = moon.coord + DVec(0, moon.radius + 100000)
val ship_init_velocity = speedToHaveOrbitWithParams(ship_start_position, 900000, moon.coord, moon.linearVelocity, moon.mass, G, ccw = false)//satelliteSpeed(ship_start_position, moon.coord, moon.linearVelocity, moon.mass, G, counterclockwise = false)
//val ship_init_velocity = satelliteSpeed(ship_start_position, earth.coord, earth.linearVelocity, earth.mass, G, counterclockwise = true)*1.15

val player_ship = new Ship4(ScageId.nextId,
Expand Down Expand Up @@ -1126,7 +1129,7 @@ object OrbitalKiller extends ScageScreenAppDMT("Orbital Killer", property("scree
if (mouse_point_further_on_the_way) {
val orbital_point = h.orbitalPointInPoint(mouse_point)
drawFilledCircle(orbital_point * scale, 3 / globalScale, ellipse_color)
val flight_time_msec = h.travelTimeOnOrbitMsec(bs_coord, orbital_point, ccw)
lazy val flight_time_msec = h.travelTimeOnOrbitMsec(bs_coord, orbital_point, ccw)

if (set_stop_moment) {
_stop_after_number_of_tacts = (flight_time_msec / 1000 / base_dt).toLong
Expand All @@ -1151,13 +1154,13 @@ object OrbitalKiller extends ScageScreenAppDMT("Orbital Killer", property("scree
!si.isMinimized && !si.monitoring_ship.isCrashed && !player_ship.isDockedToShip(si.monitoring_ship)
}).flatMap(_.monitoring_ship.thisOrActualProxyShipOrbitData).foreach(x => {
x.ellipseOrbit.foreach(e => {
val position_after_time = e.orbitalPointAfterTimeCCW(x.bs_coord, flight_time_msec / 1000)
val position_after_time = e.orbitalPointAfterTime(x.bs_coord, flight_time_msec / 1000, x.ccw)
drawCircle(position_after_time * scale, w/globalScale, YELLOW)
})
})
moon.orbitRender.foreach(x => {
x.ellipseOrbit.foreach(e => {
val position_after_time = e.orbitalPointAfterTimeCCW(x.bs_coord, flight_time_msec / 1000)
val position_after_time = e.orbitalPointAfterTime(x.bs_coord, flight_time_msec / 1000, x.ccw)
drawCircle(position_after_time * scale, moon.radius * scale, YELLOW)
drawCircle(position_after_time * scale, moon.half_hill_radius * scale, color = DARK_GRAY)
})
Expand All @@ -1171,7 +1174,7 @@ object OrbitalKiller extends ScageScreenAppDMT("Orbital Killer", property("scree
x.ellipseOrbit.foreach(e => {
if (_stop_after_number_of_tacts > 0) {
val time_to_stop_sec = (_stop_after_number_of_tacts * base_dt).toLong
val position_when_stop_moment = e.orbitalPointAfterTimeCCW(x.bs_coord, time_to_stop_sec)
val position_when_stop_moment = e.orbitalPointAfterTime(x.bs_coord, time_to_stop_sec, x.ccw)
drawCircle(position_when_stop_moment * scale, w/globalScale, GREEN)
}
})
Expand All @@ -1180,7 +1183,7 @@ object OrbitalKiller extends ScageScreenAppDMT("Orbital Killer", property("scree
x.ellipseOrbit.foreach(e => {
if (_stop_after_number_of_tacts > 0) {
val time_to_stop_sec = (_stop_after_number_of_tacts * base_dt).toLong
val position_when_stop_moment = e.orbitalPointAfterTimeCCW(x.bs_coord, time_to_stop_sec)
val position_when_stop_moment = e.orbitalPointAfterTime(x.bs_coord, time_to_stop_sec, x.ccw)
drawCircle(position_when_stop_moment * scale, moon.radius * scale, GREEN)
drawCircle(position_when_stop_moment * scale, moon.half_hill_radius * scale, color = DARK_GRAY)
}
Expand Down Expand Up @@ -1252,7 +1255,7 @@ object OrbitalKiller extends ScageScreenAppDMT("Orbital Killer", property("scree
}
val true_anomaly_rad = e.tetaRad2PiInPoint(mouse_point)

val flight_time_msec = e.travelTimeOnOrbitMsec(bs_coord, orbital_point, ccw)
lazy val flight_time_msec = e.travelTimeOnOrbitMsec(bs_coord, orbital_point, ccw)

if (set_stop_moment) {
_stop_after_number_of_tacts = (flight_time_msec / 1000 / base_dt).toLong
Expand All @@ -1277,11 +1280,11 @@ object OrbitalKiller extends ScageScreenAppDMT("Orbital Killer", property("scree
!si.isMinimized && !si.monitoring_ship.isCrashed && !player_ship.isDockedToShip(si.monitoring_ship)
}).flatMap(_.monitoring_ship.thisOrActualProxyShipOrbitData).foreach(x => {
x.ellipseOrbit.foreach(e => {
val position_after_time = e.orbitalPointAfterTimeCCW(x.bs_coord, flight_time_msec / 1000)
val position_after_time = e.orbitalPointAfterTime(x.bs_coord, flight_time_msec / 1000, x.ccw)
drawCircle(position_after_time * scale, w/globalScale, YELLOW)
if (_stop_after_number_of_tacts > 0) {
val time_to_stop_sec = (_stop_after_number_of_tacts * base_dt).toLong
val position_when_stop_moment = e.orbitalPointAfterTimeCCW(x.bs_coord, time_to_stop_sec)
val position_when_stop_moment = e.orbitalPointAfterTime(x.bs_coord, time_to_stop_sec, x.ccw)
drawCircle(position_when_stop_moment * scale, w/globalScale, GREEN)
}
})
Expand Down Expand Up @@ -1314,6 +1317,8 @@ object OrbitalKiller extends ScageScreenAppDMT("Orbital Killer", property("scree
//println("updateOrbits")
if (player_ship.flightMode == Maneuvering || !onPause || !player_ship.engines.exists(_.active)) {
// если в режиме маневрирования, или не в режиме маневрирования, но не на паузе, или на паузе, но двигатели не работают - рисуем текущее состояние
moon.orbitRender = updateOrbitData(update_count, moon.index, moon.radius, player_ship.colorIfPlayerAliveOrRed(GREEN), player_ship.colorIfPlayerAliveOrRed(GREEN), system_evolution.allBodyStates, Set(earth.index, sun.index))
earth.orbitRender = updateOrbitData(update_count, earth.index, earth.radius, player_ship.colorIfPlayerAliveOrRed(ORANGE), player_ship.colorIfPlayerAliveOrRed(ORANGE), system_evolution.allBodyStates, Set(sun.index))
player_ship.updateOrbitData(update_count, player_ship.colorIfPlayerAliveOrRed(YELLOW), player_ship.colorIfPlayerAliveOrRed(YELLOW), timeMsec, system_evolution.allBodyStates)
InterfaceHolder.orbitInfo.markUpdateNeeded()
InterfaceHolder.shipInterfaces.foreach(si => {
Expand All @@ -1322,13 +1327,13 @@ object OrbitalKiller extends ScageScreenAppDMT("Orbital Killer", property("scree
si.markUpdateNeeded()
}
})
moon.orbitRender = updateOrbitData(update_count, moon.index, moon.radius, player_ship.colorIfPlayerAliveOrRed(GREEN), player_ship.colorIfPlayerAliveOrRed(GREEN), system_evolution.allBodyStates, Set(earth.index, sun.index))
earth.orbitRender = updateOrbitData(update_count, earth.index, earth.radius, player_ship.colorIfPlayerAliveOrRed(ORANGE), player_ship.colorIfPlayerAliveOrRed(ORANGE), system_evolution.allBodyStates, Set(sun.index))
} else {
// в эту секцию мы попадаем, если мы не в режиме маневрирования, на паузе, и двигатели работают
val stop_moment = player_ship.engines.map(_.stopMomentTacts).max
val system_state_when_engines_off = getFutureState(stop_moment)
val stop_moment_msec = (stop_moment*base_dt*1000).toLong
val stop_moment_tacts = player_ship.engines.map(_.stopMomentTacts).max
val system_state_when_engines_off = getFutureState(stop_moment_tacts)
moon.orbitRender = updateOrbitData(update_count, moon.index, moon.radius, player_ship.colorIfPlayerAliveOrRed(GREEN), player_ship.colorIfPlayerAliveOrRed(GREEN), system_state_when_engines_off, Set(earth.index, sun.index))
earth.orbitRender = updateOrbitData(update_count, earth.index, earth.radius, player_ship.colorIfPlayerAliveOrRed(ORANGE), player_ship.colorIfPlayerAliveOrRed(ORANGE), system_state_when_engines_off, Set(sun.index))
val stop_moment_msec = (stop_moment_tacts*base_dt*1000).toLong
player_ship.updateOrbitData(update_count, player_ship.colorIfPlayerAliveOrRed(YELLOW), player_ship.colorIfPlayerAliveOrRed(YELLOW), stop_moment_msec, system_state_when_engines_off)
InterfaceHolder.orbitInfo.markUpdateNeeded()
InterfaceHolder.shipInterfaces.foreach(si => {
Expand All @@ -1337,8 +1342,6 @@ object OrbitalKiller extends ScageScreenAppDMT("Orbital Killer", property("scree
si.markUpdateNeeded()
}
})
moon.orbitRender = updateOrbitData(update_count, moon.index, moon.radius, player_ship.colorIfPlayerAliveOrRed(GREEN), player_ship.colorIfPlayerAliveOrRed(GREEN), system_state_when_engines_off, Set(earth.index, sun.index))
earth.orbitRender = updateOrbitData(update_count, earth.index, earth.radius, player_ship.colorIfPlayerAliveOrRed(ORANGE), player_ship.colorIfPlayerAliveOrRed(ORANGE), system_state_when_engines_off, Set(sun.index))
}
update_count += 1
_update_orbits = false
Expand Down
Expand Up @@ -1096,11 +1096,15 @@ package object orbitalkiller {
* @param G - гравитационная постоянная
* @return двумерный вектор скорости
*/
def speedToHaveOrbitWithParams(perigee_coord: DVec, apogee_diff: Double, planet_coord: DVec, planet_velocity: DVec, planet_mass: Double, G: Double): DVec = {
def speedToHaveOrbitWithParams(perigee_coord: DVec, apogee_diff: Double, planet_coord: DVec, planet_velocity: DVec, planet_mass: Double, G: Double, ccw: Boolean = true): DVec = {
val r_p = perigee_coord.dist(planet_coord)
val r_a = r_p + apogee_diff
val mu = planet_mass * G
planet_velocity + math.sqrt(-2 * mu / (r_p + r_a) + 2 * mu / r_p) * (perigee_coord - planet_coord).p
if(ccw) {
planet_velocity + math.sqrt(-2 * mu / (r_p + r_a) + 2 * mu / r_p) * (perigee_coord - planet_coord).p
} else {
planet_velocity - math.sqrt(-2 * mu / (r_p + r_a) + 2 * mu / r_p) * (perigee_coord - planet_coord).p
}
}

def timeStr(time_msec: Long, add_plus_sign: Boolean = false): String = {
Expand Down Expand Up @@ -1290,7 +1294,8 @@ package object orbitalkiller {
}
}

val f_minus_f2 = f - f2
lazy val f_minus_f2 = f - f2
lazy val f_minus_f2_n = f_minus_f2.n
val inv_n = a * math.sqrt(a / mu) // это 1/n

def tetaDeg360ByDir(dir: DVec) = f_minus_f2.deg360(dir)
Expand Down Expand Up @@ -1365,22 +1370,28 @@ package object orbitalkiller {
val xl2 = math.acos(1 - (r1 + r2 - s) / (2 * a))
// Балк М.Б. Элементы динамики космического полета, Формула Ламберта, стр 128-129: выбор чисел l1, l2 среди корней уравнения
// для эллиптической орбиты, анализ проведен английским математиком А. Кэли
val (l1, l2, /*variant*/ _) = if (t1 == 0) {
val (l1, l2, _) = if (t1 == 0) {
if (t2 < 180) (xl1, xl2, "None")
else (2 * math.Pi - xl1, -xl2, "F & A")
} else if(t2 == 0) {
if(t1 > 180) (xl1, xl2, "None")
else (2 * math.Pi - xl1, -xl2, "F & A")
} else {
if (areLinesIntersect(f2 + (f2 - f).n * r_p, f2, orbital_point1, orbital_point2)) {
if (areLinesIntersect(f2 - f_minus_f2_n * r_p, f2, orbital_point1, orbital_point2)) {
if (t2 > t1) (xl1, xl2, "None")
else (2 * math.Pi - xl1, -xl2, "F & A")
} else if (areLinesIntersect(f, f + (f - f2).n * r_p, orbital_point1, orbital_point2)) {
} else if (areLinesIntersect(f, f + f_minus_f2_n * r_p, orbital_point1, orbital_point2)) {
if (t1 > t2) (xl1, xl2, "None")
else (2 * math.Pi - xl1, -xl2, "F & A")
} else if (areLinesIntersect(f2, f, orbital_point1, orbital_point2)) {
if (t2 > t1) (2 * math.Pi - xl1, xl2, "F")
else (xl1, -xl2, "A")
} else {
if (t2 > t1) (xl1, xl2, "None")
else (2 * math.Pi - xl1, -xl2, "F & A")
if (t2 > t1) {
(xl1, xl2, "None")
} else {
(2 * math.Pi - xl1, -xl2, "F & A")
}
}
}
/*if(print_variant) {
Expand Down Expand Up @@ -1489,8 +1500,8 @@ package object orbitalkiller {

def orbitalPointAfterTimeCW(point1: DVec, time_sec: Long, num_iterations: Int = default_num_iterations): DVec = {
val t1 = tetaDeg360InPoint(point1)
val time_from_r_p = travelTimeOnOrbitMsecCW(0, t1 /*, print_variant = true*/)
val all_time = t.toLong - (time_from_r_p / 1000 + time_sec)
val time_from_r_p_msec = travelTimeOnOrbitMsecCW(0, t1 /*, print_variant = true*/)
val all_time = t.toLong - (time_from_r_p_msec / 1000 + time_sec)
val M = 1 / inv_n * all_time
val E7 = (1 to num_iterations).foldLeft(M) {
case (res, i) => _iteration(res, M)
Expand Down
Expand Up @@ -113,6 +113,9 @@ case class Orbit2(
val (l1, l2, variant) = if (t1 == 0) {
if (t2 < 180) (xl1, xl2, "None")
else (2 * math.Pi - xl1, -xl2, "F & A")
} else if(t2 == 0) {
if(t1 > 180) (xl1, xl2, "None")
else (2 * math.Pi - xl1, -xl2, "F & A")
} else {
if (areLinesIntersect(f2 + (f2 - f1).n * r_p, f2, orbital_point1, orbital_point2)) {
if (t2 > t1) (xl1, xl2, "None")
Expand Down Expand Up @@ -166,18 +169,18 @@ object OrbitPositionTest extends ScageScreenAppD("Orbit Position Test", 640, 640

private var _m: DVec = DVec.zero

//private var mr1:Option[DVec] = Some(o.f1 + (o.f1 - o.f2).n.rotateDeg(45)*ro(o.f1 + (o.f1 - o.f2).n.rotateDeg(45)))
//private var mr1:Option[DVec] = Some(o.f1 + (o.f1 - o.f2).n*o.r_p)
private var mr1: Option[DVec] = Some(o.f2 + (o.f2 - o.f1).n * o.r_p)
private var mr2: Option[DVec] = None
//private var flight_time:Option[List[String]] = None
private var flight_time: Option[String] = None


val G: Double = 6.6742867E-11
val earth_mass = 5.9746E24
val mu = G * earth_mass

//private var mr1:Option[DVec] = Some(o.f1 + (o.f1 - o.f2).n.rotateDeg(45)*ro(o.f1 + (o.f1 - o.f2).n.rotateDeg(45)))
//private var mr1:Option[DVec] = Some(o.f1 + (o.f1 - o.f2).n*o.r_p)
private var mr1: Option[DVec] = Some(o.f1 + (o.f1 - o.f2).p * o.r_p)
private var mr2: Option[DVec] = Some(o.f1 + (o.f1 - o.f2).n * o.r_p)
//private var flight_time:Option[List[String]] = None
val (time, variant) = o.travelTimeOnOrbitMsecCCW(mr1.get, mr2.get, mu)
private var flight_time: Option[String] = Some(s"${timeStr(time)}, $variant")

def msecOrKmsec(msec: Number): String = {
if (math.abs(msec.doubleValue()) < 1000) f"${msec.doubleValue()}%.2f м/сек" else f"${msec.doubleValue() / 1000}%.2f км/сек"
}
Expand Down Expand Up @@ -225,15 +228,15 @@ object OrbitPositionTest extends ScageScreenAppD("Orbit Position Test", 640, 640
}*/
})

mouseMotion(onMotion = m => {
/*mouseMotion(onMotion = m => {
_m = absCoord(m)
val mm = _m / scale
mr2 = Some(o.f1 + (mm - o.f1).n * ro(mm))
val (time, variant) = o.travelTimeOnOrbitMsecCCW(mr1.get, mr2.get, mu)
flight_time = Some(s"${timeStr(time)}, $variant")
//println(ro(_m/scale))
})

*/
/*action(100) {
_a = (_a + 1) % 360
}*/
Expand Down

0 comments on commit 0916162

Please sign in to comment.