Created
March 16, 2010 12:18
-
-
Save karno/333906 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using Microsoft.Xna.Framework; | |
using Microsoft.Xna.Framework.Audio; | |
using Microsoft.Xna.Framework.Content; | |
using Microsoft.Xna.Framework.GamerServices; | |
using Microsoft.Xna.Framework.Graphics; | |
using Microsoft.Xna.Framework.Input; | |
using Microsoft.Xna.Framework.Media; | |
using Microsoft.Xna.Framework.Net; | |
using Microsoft.Xna.Framework.Storage; | |
namespace Pastiche.Common | |
{ | |
public static class MathEx | |
{ | |
/// <summary> | |
/// 指定した速度で移動します。 | |
/// </summary> | |
/// <param name="origin">始点</param> | |
/// <param name="dest">終点</param> | |
/// <param name="speed">スピード</param> | |
/// <returns>位置の列挙</returns> | |
public static IEnumerable<Vector2> GetMovePosition(this Vector2 origin, Vector2 dest, float speed) | |
{ | |
Vector2 unit = origin - dest; | |
float unitlen = unit.Length(); | |
unit.X /= unitlen * speed; | |
unit.Y /= unitlen * speed; | |
int reqframes = (int)Math.Ceiling((origin.X - unit.X) / unit.X); | |
for (int i = 0; i < reqframes; i++) | |
{ | |
origin += unit; | |
yield return origin; | |
} | |
yield return dest; | |
} | |
/// <summary> | |
/// 指定したフレーム数を使用して移動します。 | |
/// </summary> | |
/// <param name="origin">始点</param> | |
/// <param name="dest">終点</param> | |
/// <param name="frames">使用フレーム数</param> | |
/// <returns>位置の列挙</returns> | |
public static IEnumerable<Vector2> GetMovePositionWithFrames(this Vector2 origin, Vector2 dest, int frames) | |
{ | |
Vector2 unit = dest - origin; | |
unit.X /= frames; | |
unit.Y /= frames; | |
for (int i = 0; i < frames; i++) | |
{ | |
origin += unit; | |
yield return origin; | |
} | |
yield return dest; | |
} | |
/// <summary> | |
/// 減速しながら移動します。 | |
/// </summary> | |
/// <param name="origin">始点</param> | |
/// <param name="dest">終点</param> | |
/// <param name="maxspeed">最高速度</param> | |
/// <param name="brake">減速度(1.0以上を指定してください)</param> | |
/// <returns>位置の列挙</returns> | |
public static IEnumerable<Vector2> GetMovePositionWithSlowing(this Vector2 origin, Vector2 dest, float maxspeed, float brake) | |
{ | |
//距離差 | |
Vector2 dist = dest - origin; | |
float length = dist.Length(); | |
//単位加速度(L/frames) | |
Vector2 unit = new Vector2(dist.X / length, dist.Y / length); | |
//単位あたりの最大加速度 | |
Vector2 maxvector = new Vector2((float)(dist.X / length * maxspeed), (float)(dist.Y / length * maxspeed)); | |
float mvnorm = maxvector.Length(); | |
while ((dest.X - origin.X) * dist.X > 0 && (dest.Y - origin.Y) * dist.Y > 0) | |
{ | |
Vector2 cv = unit * brake * (dest - origin).Length(); | |
if (cv.X == 0 || cv.Y == 0) | |
break; | |
if (cv.Length() > mvnorm) | |
origin += maxvector; | |
else | |
origin += cv; | |
yield return origin; | |
} | |
yield return dest; | |
} | |
/// <summary> | |
/// エルミート曲線を用いて移動します。 | |
/// </summary> | |
/// <param name="init">始点</param> | |
/// <param name="dest">終点</param> | |
/// <param name="initvector">始点接線ベクトル</param> | |
/// <param name="destvector">終点接線ベクトル</param> | |
/// <param name="frames">移動フレーム</param> | |
/// <returns>位置の列挙</returns> | |
public static IEnumerable<Vector2> GetMovePositionByHermite(Vector2 origin, Vector2 dest, | |
Vector2 origvector, Vector2 destvector, int frames) | |
{ | |
for (int i = 0; i < frames; i++) | |
{ | |
float u1 = i * 1.0f / (frames - 1); | |
float u2 = u1 * u1; | |
float u3 = u2 * u1; | |
float mP0 = 2 * u3 - 3 * u2 + 1; | |
float mV0 = u3 - 2 * u2 + u1; | |
float mP1 = -2 * u3 + 3 * u2; | |
float mV1 = u3 - u2; | |
yield return new Vector2( | |
origin.X * mP0 + origvector.X * mV0 + dest.X * mP1 + destvector.X * mV1, | |
origin.Y * mP0 + origvector.Y * mV0 + dest.Y * mP1 + destvector.Y * mV1); | |
} | |
} | |
/// <summary> | |
/// 指定した範囲内でランダムに場所を決定し、ベクトルとして返します。[非推奨] | |
/// </summary> | |
/// <param name="region">限定する移動先リージョン</param> | |
/// <returns>移動先ベクトル</returns> | |
public static Vector2 GetRundomPosition(this Rectangle region) | |
{ | |
return new Vector2(MTwister.Next(region.Left, region.Right), MTwister.Next(region.Left, region.Right)); | |
} | |
/// <summary> | |
/// 指定したラジアンとノルムから二次元ベクトルを生成します。 | |
/// </summary> | |
/// <param name="rad">ラジアン</param> | |
/// <param name="norm">ノルム</param> | |
/// <returns>二次元ベクトル</returns> | |
public static Vector2 CreateVector(double rad, float norm) | |
{ | |
return new Vector2((float)Math.Cos(rad) * norm, (float)Math.Sin(rad) * norm); | |
} | |
/// <summary> | |
/// 弧度法における度数をラジアンに変換します。 | |
/// </summary> | |
/// <param name="deg">度数</param> | |
/// <returns>ラジアン</returns> | |
public static double ToRadian(this double deg) | |
{ | |
return deg * Math.PI / 180.0; | |
} | |
/// <summary> | |
/// ラジアンを弧度法における度数に変換します。 | |
/// </summary> | |
/// <param name="rad">ラジアン</param> | |
/// <returns>度数</returns> | |
public static double ToDegree(this double rad) | |
{ | |
return rad * 180.0 / Math.PI; | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment