public static double WheelTurnForEndZeroWheelTurnToPoint(this PCar car, Vector point, double finalAngle, double sign) { PCar physicCar = new PCar(car); int ticks = (int)Math.Abs(Math.Round(physicCar.WheelTurn / game.CarWheelTurnChangePerTick)); AngleReachEvent angleReach = new AngleReachEvent(finalAngle); MoveToAngleFunction mover = new MoveToAngleFunction(finalAngle); for (int i = 0; i < ticks; i++) { mover.Iteration(physicCar, 1); if (angleReach.Check(physicCar)) { break; } } Vector dir = physicCar.Speed.Length < 1 ? physicCar.Dir : physicCar.Dir * 0.8 + physicCar.Speed.Normalize() * 0.2; double distance = -(point - physicCar.Pos).Cross(dir); if (Math.Abs(distance) < 10) { return(0); } return(car.WheelTurn + sign * game.CarWheelTurnChangePerTick * Math.Sign(distance)); }
public static double WheelTurnForEndZeroWheelTurn(this PCar car, double finalAngle, double sign) { PCar physicCar = new PCar(car); int ticks = (int)Math.Abs(Math.Round(physicCar.WheelTurn / game.CarWheelTurnChangePerTick)); physicCar.setWheelTurn(0); physicCar.Iteration(ticks); double angleDeviation = finalAngle.AngleDeviation(physicCar.Angle); if (sign < 0) { Vector v = Vector.sincos(finalAngle + Math.PI); double inverse90Angle = Math.Abs(v.X) > Math.Abs(v.Y) ? ((Math.Sign(v.X) - 1) * Math.PI / 2) : (Math.Sign(v.Y) * Math.PI / 2); if (Math.Abs(Math.Abs(v.X) - Math.Abs(v.Y)) < 1.0e-3)//45 { inverse90Angle = v.Angle; } double angleSub = inverse90Angle.AngleDeviation(physicCar.Angle); angleDeviation = finalAngle.AngleDeviation(physicCar.Angle + 2 * angleSub); } if (Math.Abs(angleDeviation) < game.CarRotationFrictionFactor) { return(0); } return(car.WheelTurn + game.CarWheelTurnChangePerTick * Math.Sign(angleDeviation)); }
public override bool Check(PCar car) { CollisionRect carRect = new CollisionRect(car); List <CollisionInfo> collisions = CollisionDetector.CheckCollision(carRect, collisionObjects); if (!collisions.HasCollision()) { return(false); } foreach (CollisionInfo info in collisions) { if (!info.CollisionDeletected) { continue; } Vector normal = info.NormalObj1; if (car.Dir.Dot(normal) > -1.0e-2) { continue; } checkInfo = new Tuple <Vector, Vector>(info.Point, normal); return(true); } return(false); }
private bool hasReserveTicks(PCar iterCar, Vector needDirAngle) { MoveToPoint mover = null; if (null != needPos) { mover = new MoveToPoint(needPos, needDirAngle.Angle); } else { mover = new MoveToPoint(defaultPos); } PCar car = new PCar(iterCar); for (int tick = 0; tick < 5; tick++) { HashSet <IPhysicEvent> events = calculateTurnEvents(car, needDirAngle); if (events.ComeContaints(PhysicEventType.OutLine)) { return(false); } mover.Iteration(car, 1); } return(true); }
private int moveOnDistance(PCar car, Vector needDirAngle, double distance) { MoveToPoint mover = null; if (null != needPos) { mover = new MoveToPoint(needPos, needDirAngle.Angle); } else { mover = new MoveToPoint(defaultPos); } double speedL = car.Speed.Length; int addTick = 1; if (speedL > 1.0e-3) { addTick = (int)Math.Max(1, Math.Min(0.5 * distance / speedL, 1024)); } else { addTick = 2; } mover.Iteration(car, addTick); return(addTick); }
/// avoid map crash private HashSet <IPhysicEvent> calculateAvoidMapCrashEvents(Move currentMove) { HashSet <IPhysicEvent> pEvents = new HashSet <IPhysicEvent> { new MapCrashEvent() }; if (null != moverSelfMapCrashEvent) { pEvents.Add(moverSelfMapCrashEvent.Copy()); } if (null != passageLineEvent) { pEvents.Add(passageLineEvent.Copy()); } PCar physicCar = new PCar(car, game); physicCar.setEnginePower(currentMove.EnginePower); physicCar.setWheelTurn(0);//currentMove.WheelTurn physicCar.setBrake(currentMove.IsBrake); PhysicEventsCalculator.calculateEvents(physicCar, new MoveWithOutChange(), pEvents, calculateAvoidSideCrashEventCheckEnd); return(pEvents); }
public CollisionRect(PCar car) { this.Center = car.Pos; this.Dir = car.Dir; this.Width = car.Car.Width; this.Height = car.Car.Height; this.Points = calculatePoints(); }
private bool calculateMoveEventCheckEnd(PCar physicCar, HashSet <IPhysicEvent> pEvents, int tick) { if (tick > maxCheckMoveCrashIterationCount) { return(true); } return(pEvents.ComeContaints(PhysicEventType.MapCrash) || pEvents.ComeContaints(PhysicEventType.ObjectsCrash)); }
public static PCar GetZeroWheelTurnCar(this PCar car) { PCar physicCar = new PCar(car); int ticks = (int)Math.Abs(Math.Round(physicCar.WheelTurn / game.CarWheelTurnChangePerTick)); physicCar.setWheelTurn(0); physicCar.Iteration(ticks); return(physicCar); }
private bool calculateAvoidSideCrashEventCheckEnd(PCar physicCar, HashSet <IPhysicEvent> pEvents, int tick) { if (tick > maxCheckCrashIterationCount) { return(true); } //physicCar.setBrake(false); return(pEvents.ComeContaints(PhysicEventType.PassageLine) || pEvents.ComeContaints(PhysicEventType.MapCrash)); }
private bool moveToAddPointEventCheckEnd(PCar physicCar, HashSet <IPhysicEvent> pEvents, int tick) { if (tick > maxIterationCount) { return(true); } return(pEvents.ComeContaints(PhysicEventType.MapCrash) || pEvents.ComeContaints(PhysicEventType.PassageLine) || pEvents.ComeContaints(PhysicEventType.ObjectsCrash)); }
public static double WheelTurnForEndZeroWheelTurn(this PCar car, Vector finalPos, double sign) { PCar physicCar = new PCar(car); int ticks = (int)Math.Abs(Math.Round(physicCar.WheelTurn / game.CarWheelTurnChangePerTick)); physicCar.setWheelTurn(0); physicCar.Iteration(ticks); double finalAngle = (finalPos - car.Pos).Angle; return(car.WheelTurnForEndZeroWheelTurn(finalAngle, sign)); }
private void avoidSideCrash(Move moveResult, Vector needDirAngle = null) { HashSet <IPhysicEvent> events = calculateAvoidMapCrashEvents(moveResult); IPhysicEvent passageLine = events.ComeContaints(PhysicEventType.PassageLine) ? events.GetEvent(PhysicEventType.PassageLine) : null; IPhysicEvent mapCrash = events.ComeContaints(PhysicEventType.MapCrash) ? events.GetEvent(PhysicEventType.MapCrash) : null; IPhysicEvent objectsCrash = events.ComeContaints(PhysicEventType.ObjectsCrash) ? events.GetEvent(PhysicEventType.ObjectsCrash) : null; IPhysicEvent crash = (null != objectsCrash && objectsCrash.TickCome > 1) ? objectsCrash : mapCrash; if (null != crash) { int tickToPassageLine = (null != passageLine) ? passageLine.TickCome : maxIterationCount; if (crash.TickCome < tickToPassageLine) { Vector dir = new Vector(dirMove.X, dirMove.Y); PCar physicCar = crash.CarCome; Tuple <Vector, Vector> crashInfo = crash.infoCome as Tuple <Vector, Vector>; Logger.instance.Assert(null != crashInfo, "Can't get crash info"); Vector sideNormal = crashInfo.Item2; double angle = dir.Angle.AngleDeviation(sideNormal.Angle); if (Vector.sincos(car.Angle).Dot(dir) > 0 || 0 == angle) { angle = car.Angle.AngleDeviation(sideNormal.Angle); } bool notCurrentTurnSide = null != needDirAngle && sideNormal.Dot(needDirAngle) > 0; if (!checkStrongParallel(crash) || notCurrentTurnSide) { moveResult.WheelTurn = car.WheelTurn - speedSign * Math.Sign(angle) * game.CarWheelTurnChangePerTick; } bool isParallel = Vector.sincos(car.Angle).Dot(sideNormal).LessDotWithAngle(Math.PI / 9); //20 degrees isParallel |= physicCar.Dir.Dot(sideNormal).LessDotWithAngle(Math.PI / 9); //20 degrees int ticksToZeroEnginePower = (int)(Math.Abs(car.EnginePower) / game.CarEnginePowerChangePerTick); if (!isParallel && speedSign > 0 && crash.TickCome < ticksToZeroEnginePower) { if (moveResult.EnginePower > 0.5) { moveResult.EnginePower -= game.CarEnginePowerChangePerTick; } } if (!isParallel) { moveResult.IsBrake = moveResult.IsBrake || car.Speed() > Constant.MinBrakeSpeed; } } } }
public override bool Check(PCar car) { foreach (OilSlick stick in world.OilSlicks) { if ((car.Pos - new Vector(stick.X, stick.Y)).Length < stick.Radius) { car.traveledOnOil(stick); checkInfo = stick; return(true); } } return(false); }
private void move(Move moveResult) { PCar physicCar = new PCar(car, game); physicCar.setEnginePower(enginePowerSign); HashSet <IPhysicEvent> events = calculateMoveEvents(physicCar); if (events.ComeContaints(PhysicEventType.MapCrash) || events.ComeContaints(PhysicEventType.ObjectsCrash)) { moveResult.WheelTurn = physicCar.WheelTurnForEndZeroWheelTurn(defaultPos, speedSign); } }
private bool calculateTurnMapCrashEventCheckEnd(PCar physicCar, HashSet <IPhysicEvent> pEvents, int tick) { if (tick > maxCheckRotateIterationCount) { return(true); } if (useBrakeForTurn) { physicCar.setBrake(physicCar.Speed.Length > Constant.MinBrakeSpeed); } return(pEvents.ComeContaints(PhysicEventType.PassageLine)); }
private bool calculateTurnEventCheckEnd(PCar physicCar, HashSet <IPhysicEvent> pEvents, int tick) { if (tick > maxIterationCount) { return(true); } if (pEvents.ComeContaints(PhysicEventType.AngleReach) && !pEvents.Containts(PhysicEventType.SpeedReach)) { pEvents.Add(new SpeedReachEvent()); } return(pEvents.ComeContaints(PhysicEventType.SpeedReach)); }
public override bool Check(PCar car) { if (OutLine(car)) { if (Math.Abs((car.LastPos - pos).Dot(normal)) < accuracity) { return(true); } return(Math.Sign((car.Pos - pos).Dot(normal)) != Math.Sign((car.LastPos - pos).Dot(normal))); } return(false); }
private void turn(Move moveResult, Vector needDirAngle) { PCar iterCar = new PCar(car, game); iterCar.setEnginePower(enginePowerSign); Vector endPoint = endTile.ToVector(1 - dirMove.X, 1 - dirMove.Y); endPoint = endPoint + new Vector(dirMove.X, dirMove.Y) * game.TrackTileMargin; double speedSign = Math.Sign(Vector.sincos(car.Angle).Dot(new Vector(car.SpeedX, car.SpeedY))); HashSet <IPhysicEvent> events = calculateTurnEvents(iterCar, needDirAngle); IPhysicEvent passageLine = events.ComeContaints(PhysicEventType.PassageLine) ? events.GetEvent(PhysicEventType.PassageLine) : null; IPhysicEvent outLine = events.ComeContaints(PhysicEventType.OutLine) ? events.GetEvent(PhysicEventType.OutLine) : null; IPhysicEvent speedReach = events.ComeContaints(PhysicEventType.SpeedReach) ? events.GetEvent(PhysicEventType.SpeedReach) : null; if (null != passageLine && null != outLine) { int speedReachTick = null != speedReach ? speedReach.TickCome : maxIterationCount; if (speedReachTick * iterCar.CalculateBrakeFactor() > outLine.TickCome) { moveResult.IsBrake = car.Speed() > Constant.MinBrakeSpeed; } } if (!hasReserveTicks(iterCar, needDirAngle)) { HashSet <IPhysicEvent> crashEvents = calculateTurnMapCrashEvents(iterCar, needDirAngle, moveResult.IsBrake); IPhysicEvent mapBrakeCrash = crashEvents.ComeContaints(PhysicEventType.ObjectsCrash) ? crashEvents.GetEvent(PhysicEventType.ObjectsCrash) : null; IPhysicEvent passageLineBrake = crashEvents.ComeContaints(PhysicEventType.PassageLine) ? crashEvents.GetEvent(PhysicEventType.PassageLine) : null; //bool endMove = checkStrongParallel(mapBrakeCrash); int tickToZeroWheelTurn = (int)Math.Round(Math.Abs(iterCar.WheelTurn / game.CarWheelTurnChangePerTick)); bool nearEndAndCrash = (null != mapBrakeCrash && null != passageLine && mapBrakeCrash.TickCome <= tickToZeroWheelTurn && passageLine.TickCome < tickToZeroWheelTurn); if ((null == mapBrakeCrash && null != passageLineBrake) || nearEndAndCrash) { moveResult.WheelTurn = new PCar(car, game).WheelTurnForEndZeroWheelTurn(needDirAngle.Angle, speedSign); } } if (isMovedOutFromLine(iterCar, needDirAngle)) { moveResult.WheelTurn = new PCar(car, game).WheelTurnForEndZeroWheelTurn(needDirAngle.Angle, speedSign); } }
public void Iteration(PCar car, int iterationCount) { for (int i = 0; i < iterationCount; i++) { if (intersecOildStickEvent.Check(car)) { car.traveledOnOil(intersecOildStickEvent.InfoForCheck as OilSlick); } double speedSign = Math.Sign(car.Dir.Dot(car.Speed)); double wheelTurn = car.WheelTurnForEndZeroWheelTurn(angle, speedSign); car.setWheelTurn(wheelTurn); car.Iteration(1); } }
public PCar(PCar physicCar) : this(physicCar.car, physicCar.game) { wheelTurn = physicCar.wheelTurn; idealWheelTurn = physicCar.idealWheelTurn; enginePower = physicCar.enginePower; idealEnginePower = physicCar.idealEnginePower; pos = physicCar.pos; lastPos = physicCar.lastPos; spd = physicCar.spd; angle = physicCar.angle; dir = physicCar.dir; angleSpeed = physicCar.angleSpeed; nitroTicks = physicCar.nitroTicks; oilTicks = physicCar.oilTicks; brake = physicCar.brake; }
/// Move to Additional Point private void moveToAdditionalPoint(double needAngle) { if (null == additionalPoints) { return; } int minTicks = int.MaxValue; foreach (Tuple <Vector, double> data in additionalPoints) { Vector point = data.Item1; IPhysicEvent passageLineEvent = new PassageLineEvent(Vector.sincos(needAngle), point, 0); HashSet <IPhysicEvent> pEvents = new HashSet <IPhysicEvent> { new MapCrashEvent(), passageLineEvent }; if (null != moverSelfMapCrashEvent) { pEvents.Add(moverSelfMapCrashEvent.Copy()); } PCar physicCar = new PCar(car, game); PhysicEventsCalculator.calculateEvents(physicCar, new MoveToPoint(point, needAngle), pEvents, moveToAddPointEventCheckEnd); if (pEvents.ComeContaints(PhysicEventType.MapCrash) || pEvents.ComeContaints(PhysicEventType.ObjectsCrash) || !pEvents.ComeContaints(PhysicEventType.PassageLine)) { continue; } if (passageLineEvent.CarCome.Pos.GetDistanceTo(point) > data.Item2) { continue; } if (passageLineEvent.TickCome < minTicks) { needPos = point; } } }
private HashSet <IPhysicEvent> calculateTurnMapCrashEvents(PCar iterCar, Vector needDirAngle, bool isBrake) { HashSet <IPhysicEvent> pEvents = new HashSet <IPhysicEvent> { passageLineEvent.Copy() }; if (null != moverSelfMapCrashEvent) { pEvents.Add(moverSelfMapCrashEvent.Copy()); } PCar physicCar = new PCar(iterCar); useBrakeForTurn = isBrake; physicCar.setBrake(isBrake); PhysicEventsCalculator.calculateEvents(physicCar, new MoveToAngleFunction(needDirAngle.Angle), pEvents, calculateTurnMapCrashEventCheckEnd); return(pEvents); }
/// Turn private HashSet <IPhysicEvent> calculateTurnEvents(PCar iterCar, Vector needDirAngle) { HashSet <IPhysicEvent> pEvents = new HashSet <IPhysicEvent> { passageLineEvent.Copy(), outLineEvent.Copy(), angleReachEvent.Copy() }; PCar physicCar = new PCar(iterCar); PhysicEventsCalculator.calculateEvents(physicCar, new MoveToAngleFunction(needDirAngle.Angle), pEvents, calculateTurnEventCheckEnd); if (!pEvents.Containts(PhysicEventType.SpeedReach)) { pEvents.Add(new SpeedReachEvent()); } return(pEvents); }
///Move private HashSet <IPhysicEvent> calculateMoveEvents(PCar iterCar) { HashSet <IPhysicEvent> pEvents = new HashSet <IPhysicEvent> { new MapCrashEvent() }; if (null != moverSelfMapCrashEvent) { pEvents.Add(moverSelfMapCrashEvent.Copy()); } PCar physicCar = new PCar(iterCar); /*if (null != needPos) { * PhysicEventsCalculator.calculateEvents(physicCar, new MoveToAngleFunction(Math.Atan2(dirMove.Y, dirMove.X)), pEvents, calculateMoveEventCheckEnd); * } else {*/ PhysicEventsCalculator.calculateEvents(physicCar, new MoveToAngleFunction(car.GetAbsoluteAngleTo(defaultPos.X, defaultPos.Y)), pEvents, calculateMoveEventCheckEnd); //} return(pEvents); }
public static void calculateEvents(PCar physicCar, IPhysicMoveFunction moveFunc, HashSet <IPhysicEvent> pEvents, CheckCalculateEnd checkEnd) { for (int tick = 0; tick < maxSaveIterationCount; tick++) { foreach (IPhysicEvent pEvent in pEvents) { if (!pEvent.IsCome && pEvent.Check(physicCar)) { pEvent.SetCome(physicCar, tick, pEvent.InfoForCheck); } } if (checkEnd(physicCar, pEvents, tick)) { return; } moveFunc.Iteration(physicCar, 1); } Logger.instance.Assert(false, "Please check delegate: CheckCalculateEnd."); }
public void Iteration(PCar car, int iterationCount) { for (int i = 0; i < iterationCount; i++) { if (intersecOildStickEvent.Check(car)) { car.traveledOnOil(intersecOildStickEvent.InfoForCheck as OilSlick); } double speedSign = Math.Sign(car.Dir.Dot(car.Speed)); if (double.IsNaN(finalAngle)) { car.WheelTurnForEndZeroWheelTurn(point, speedSign); } else { car.setWheelTurn(car.WheelTurnForEndZeroWheelTurnToPoint(point, finalAngle, speedSign)); } car.Iteration(1); } }
private bool isMovedOutFromLine(PCar iterCar, Vector needDirAngle) { if (outLineEvent.OutLine(iterCar)) { return(false); } MoveToPoint mover = null; if (null != needPos) { mover = new MoveToPoint(needPos, needDirAngle.Angle); } else { mover = new MoveToPoint(defaultPos); } PCar carToAngle = new PCar(iterCar); MoveToAngleFunction moveToAngle = new MoveToAngleFunction(needDirAngle.Angle); int ticksToAngle = 0; for (; ticksToAngle < 100; ticksToAngle++) { moveToAngle.Iteration(carToAngle, 1); if (angleReachEvent.Check(carToAngle)) { break; } } PCar car = new PCar(iterCar); mover.Iteration(car, ticksToAngle); return(outLineEvent.OutLine(car)); }
public bool OutLine(PCar car) { return(Math.Abs((car.Pos - pos).Dot(normal)) > accuracity); }
public override bool Check(PCar car) { TilePos carPos = new TilePos(car.Pos.X, car.Pos.Y); return(carPos != tile); }