コード例 #1
0
ファイル: Path.cs プロジェクト: geoffreylhart/MathExp
 public Path(float totalTime, Vector2 pos, Vector2 v, Vector2 a, Path prev)
 {
     this.totalTime = totalTime;
     this.pos = pos;
     this.v = v;
     this.a = a;
     this.prev = prev;
     this.time = totalTime - ((prev == null) ? 0 : prev.totalTime);
 }
コード例 #2
0
 public PointFunction(Geometry.Point p1, Geometry.Point p2, PointFunction old, float accel, float gravity)
 {
     Vector2 path = ((Vector2)p2-(Vector2)p1);
     Vector2 normalized = path;
     normalized.Normalize();
     float g = gravity * path.Y / path.Length();
     // r and l have been specifically framed this way, and affect several equations
     float r = g + accel;
     float l = -g + accel;
     float d = path.Length();
     foreach(var pair in old.timings)
     {
         // is positive if it assists acceleration towards p2 (aka right)
         float b = FromKey(pair.Key);
         // collisions reduce speed
         Vector2 prevPath = (Vector2)p1 - pair.Value.posAt(0);
         if (prevPath != Vector2.Zero)
         {
             b *= Math.Abs(Vector2.Dot(path, prevPath)) / (path.Length() * prevPath.Length());
         }
         Parabola fullSpeedPath = new Parabola(r, b, 0);
         Parabola fullRetreatPath = new Parabola(-l, b, 0);
         Paraboloid speedThenRetreat = fullSpeedPath.FollowedBy(fullRetreatPath);
         int lowerBound = ToKey(fullRetreatPath.SpeedAt(d, 0));
         int upperBound = ToKey(fullSpeedPath.SpeedAt(d, 0));
         for (int i = lowerBound; i <= upperBound; i++)
         {
             float f = FromKey(i);
             float newPartialTime = speedThenRetreat.SpecialShit(d, f, -1);
             if (newPartialTime >= 0)
             {
                 float newT = newPartialTime + pair.Value.totalTime;
                 if (!timings.ContainsKey(i) || timings[i].totalTime > newT)
                 {
                     float rT = (l * newPartialTime + f - b) / (l + r);
                     float lT = newPartialTime - rT;
                     timings[i] = new Path(newT-lT, p1, b * normalized, r * normalized, pair.Value);
                     timings[i] = new Path(newT, timings[i].posAt(rT), timings[i].vAt(rT), -l * normalized, timings[i]);
                 }
             }
         }
     }
 }
コード例 #3
0
 public PointFunction(float p)
 {
     timings[ToKey(p)] = new Path(0, Vector2.Zero, Vector2.Zero, Vector2.Zero, null);
 }
コード例 #4
0
 internal void Update()
 {
     mouseListener.Update();
     var keystate = Keyboard.GetState();
     if(keystate.IsKeyDown(Keys.Z) && !playback && isBound) // TODO: we can improve this to work even when unbound
     {
         var target = geometry.SnapToClosePoint(mouseListener.Transform(Mouse.GetState()));
         recording = PathFinding.PathTo(player2, target, geometry, ACCEL, GRAVITY);
         if (recording != null)
         {
             timeInRecording = 0;
             recordingPointer = new Particle(recording.absolutePosAt(0), Vector2.Zero, Vector2.Zero);
             playback = true;
         }
     }
     if (!playback)
     {
         if (!isBound)
         {
             var collision = geometry.FirstCollision(player);
             if (collision != null)
             {
                 isBound = true;
                 player2 = collision;
             }
         }
         if (isBound)
         {
             bool upsideDown = (((Vector2)player2.boundTo).X < 0) != player2.onCW;
             if (upsideDown)
             {
                 isBound = false;
                 player.position = player2.boundTo.p1 + Vector2.Multiply(player2.boundTo, (float)player2.g);
                 player.velocity = Vector2.Multiply(player2.boundTo, (float)player2.gv) + player.gravity;
                 player.position += player.velocity;
                 player.velocity += player.gravity;
             }
             else
             {
                 player2.g += player2.gv;
                 player2.gv += player2.ga;
                 if (keystate.IsKeyDown(Keys.A))
                 {
                     player2.gv += ACCEL * ((player2.onCW) ? 1 : -1) / ((Vector2)player2.boundTo).Length();
                 }
                 if (keystate.IsKeyDown(Keys.D))
                 {
                     player2.gv -= ACCEL * ((player2.onCW) ? 1 : -1) / ((Vector2)player2.boundTo).Length();
                 }
                 if (player2.g > 1 || player2.g < 0)
                 {
                     var exitingPoint = (player2.g < 0) ? player2.boundTo.p1 : player2.boundTo.p2;
                     var nextList = geometry.LinesAttachedTo(exitingPoint).Where(l => l != player2.boundTo);
                     nextList = nextList.Where(l => (((((Vector2)player2.boundTo).CrossProduct(l) < 0) != player2.onCW) != (player2.boundTo.p1 == exitingPoint)) != ((exitingPoint == l.p1) == (exitingPoint == player2.boundTo.p1)));
                     if (nextList.Count() > 0)
                     {
                         var next = nextList.OrderBy(l => Math.Abs(((Vector2)player2.boundTo).CrossProduct(l)) / ((Vector2)l).Length()).Last();
                         var multiplier = Vector2.Dot(next, player2.boundTo) / (((Vector2)next).Length() * ((Vector2)player2.boundTo).Length()) * ((Vector2)player2.boundTo).Length() / ((Vector2)next).Length();
                         if ((exitingPoint == next.p1) == (exitingPoint == player2.boundTo.p1))
                         {
                             player2.onCW = !player2.onCW;
                         }
                         player2.boundTo = next;
                         player2.g = (next.p1 == exitingPoint) ? 0 : 1;
                         player2.gv *= multiplier;
                         player2.ga = Vector2.Dot(player.gravity, (Vector2)next) / (((Vector2)next).LengthSquared());
                     }
                     else
                     {
                         isBound = false;
                         player.position = player2.boundTo.p1 + Vector2.Multiply(player2.boundTo, (float)player2.g);
                         player.velocity = Vector2.Multiply(player2.boundTo, (float)player2.gv);
                     }
                 }
             }
         }
         else
         {
             // order of this matters
             player.position += player.velocity;
             player.velocity += player.gravity;
         }
     }
 }