/****************************************************************************
Copyright (c) 2011-2013,WebJet Business Division,CYOU
http://www.genesis-3d.com.cn
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
namespace ScriptRuntime
{
using System;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.InteropServices;
///
/// 二维向量
///
[Serializable, StructLayout(LayoutKind.Sequential)]
public struct Vector2 : IEquatable
{
///
/// 获取或设置X分量
///
public float X;
///
/// 获取或设置Y分量
///
public float Y;
private static Vector2 _zero;
private static Vector2 _one;
private static Vector2 _unitX;
private static Vector2 _unitY;
///
/// 返回一个分量为0的二维向量
///
public static Vector2 Zero
{
get
{
return _zero;
}
}
///
/// 返回一个分量为1的二维向量
///
public static Vector2 One
{
get
{
return _one;
}
}
///
/// 返回X轴方向上的单位向量
///
public static Vector2 UnitX
{
get
{
return _unitX;
}
}
///
/// 返回Y轴方向上的单位向量
///
public static Vector2 UnitY
{
get
{
return _unitY;
}
}
///
/// 初始化一个二维向量实例
///
/// 初始化X轴方向的值
/// 初始化Y轴方向的值
public Vector2(float x, float y)
{
this.X = x;
this.Y = y;
}
///
/// 创建一个新的二维向量实例
///
/// 初始化X轴方向Y轴方向同为的值
public Vector2(float value)
{
this.X = this.Y = value;
}
///
/// 使用[0],[1]分别对应X轴分量,Y轴分量
///
/// 想要获取分量的索引
/// 想要获取的分量
public unsafe float this[int index]
{
get
{
fixed (float* th = &(this.X))
{
return th[index];
}
}
set
{
fixed (float* th = &(this.X))
{
th[index] = value;
}
}
}
///
/// 用字符串表示
///
/// 表示当前对象的字符串
public override string ToString()
{
CultureInfo currentCulture = CultureInfo.CurrentCulture;
return string.Format(currentCulture, "{0}, {1}", new object[] { this.X.ToString(currentCulture), this.Y.ToString(currentCulture) });
}
///
/// 判断当前向量与指定向量是否相等
///
/// 指定的二维向量
/// 返回是否相等
public bool Equals(Vector2 other)
{
return ((this.X == other.X) && (this.Y == other.Y));
}
///
/// 判断是否当前实例等于指定对象
///
/// 指定的对象.
/// 当前实例等于指定对象返回true,不等于返回false
public override bool Equals(object obj)
{
bool flag = false;
if (obj is Vector2)
{
flag = this.Equals((Vector2) obj);
}
return flag;
}
///
/// 获取向量对象的哈希码
///
/// 向量对象的哈希吗
public override int GetHashCode()
{
return (this.X.GetHashCode() + this.Y.GetHashCode());
}
///
/// 计算向量的模
///
/// 向量的模
public float Length()
{
float num = (this.X * this.X) + (this.Y * this.Y);
return (float)Math.Sqrt((double)num);
}
///
/// 计算向量长度值的平方
///
/// 向量长度的平方值
public float LengthSquared()
{
return ((this.X * this.X) + (this.Y * this.Y));
}
///
/// 计算两个向量之间的距离
///
/// 源向量
/// 源向量
/// 两个二维向量之间的距离
public static float Distance(Vector2 value1, Vector2 value2)
{
float num2 = value1.X - value2.X;
float num = value1.Y - value2.Y;
float num3 = (num2 * num2) + (num * num);
return (float) Math.Sqrt((double) num3);
}
///
/// 计算两个向量之间的距离
///
/// 源向量
/// 源向量
/// [输出属性] 两个向量之间的距离
public static void Distance(ref Vector2 value1, ref Vector2 value2, out float result)
{
float num2 = value1.X - value2.X;
float num = value1.Y - value2.Y;
float num3 = (num2 * num2) + (num * num);
result = (float)Math.Sqrt((double)num3);
}
///
/// 计算两个向量之间的距离的平方
///
/// 源向量
/// 源向量
/// 两个向量之间的距离的平方
public static float DistanceSquared(Vector2 value1, Vector2 value2)
{
float num2 = value1.X - value2.X;
float num = value1.Y - value2.Y;
return ((num2 * num2) + (num * num));
}
///
/// 计算两个向量之间的距离的平方
///
/// 源向量
/// 源向量
/// [输出属性] 两个向量之间的距离的平方
public static void DistanceSquared(ref Vector2 value1, ref Vector2 value2, out float result)
{
float num2 = value1.X - value2.X;
float num = value1.Y - value2.Y;
result = (num2 * num2) + (num * num);
}
///
/// 返回指定向量的单位向量,方向保持一致
///
public void Normalize()
{
float num2 = (this.X * this.X) + (this.Y * this.Y);
float num = 1f / ((float) Math.Sqrt((double) num2));
this.X *= num;
this.Y *= num;
}
///
/// 返回指定向量的单位向量,方向保持一致
///
/// 源向量
/// 被创建的单位向量
public static Vector2 Normalize(Vector2 value)
{
Vector2 vector;
float num2 = (value.X * value.X) + (value.Y * value.Y);
float num = 1f / ((float) Math.Sqrt((double) num2));
vector.X = value.X * num;
vector.Y = value.Y * num;
return vector;
}
///
/// 指定向量的单位向量,方向保持一致,用户指定变量
///
/// 源向量
/// [输出属性] 标准化向量
public static void Normalize(ref Vector2 value, out Vector2 result)
{
float num2 = (value.X * value.X) + (value.Y * value.Y);
float num = 1f / ((float)Math.Sqrt((double)num2));
result.X = value.X * num;
result.Y = value.Y * num;
}
///
/// 给出向量和法线 确定反射向量
///
/// 源向量
/// 法线向量
/// 求得的反射向量
public static Vector2 Reflect(Vector2 vector, Vector2 normal)
{
Vector2 vector2;
float num = (vector.X * normal.X) + (vector.Y * normal.Y);
vector2.X = vector.X - ((2f * num) * normal.X);
vector2.Y = vector.Y - ((2f * num) * normal.Y);
return vector2;
}
///
/// 给出向量和法线 确定反射向量
///
/// 源向量
/// 法线向量
/// [输出属性] 求得的反射向量
public static void Reflect(ref Vector2 vector, ref Vector2 normal, out Vector2 result)
{
float num = (vector.X * normal.X) + (vector.Y * normal.Y);
result.X = vector.X - ((2f * num) * normal.X);
result.Y = vector.Y - ((2f * num) * normal.Y);
}
///
/// 返回一个向量,包含每对向量分量中最小值
///
/// 源向量
/// 源向量
/// 最小向量
public static Vector2 Min(Vector2 value1, Vector2 value2)
{
Vector2 vector;
vector.X = (value1.X < value2.X) ? value1.X : value2.X;
vector.Y = (value1.Y < value2.Y) ? value1.Y : value2.Y;
return vector;
}
///
/// 返回一个向量,包含每对向量分量中最小值
///
/// 源向量
/// 源向量
/// [输出属性] 最小向量
public static void Min(ref Vector2 value1, ref Vector2 value2, out Vector2 result)
{
result.X = (value1.X < value2.X) ? value1.X : value2.X;
result.Y = (value1.Y < value2.Y) ? value1.Y : value2.Y;
}
///
/// 返回一个向量,包含每对向量分量中最大值
///
/// 源向量
/// 源向量
/// 最大向量
public static Vector2 Max(Vector2 value1, Vector2 value2)
{
Vector2 vector;
vector.X = (value1.X > value2.X) ? value1.X : value2.X;
vector.Y = (value1.Y > value2.Y) ? value1.Y : value2.Y;
return vector;
}
///
/// 返回一个向量,包含每对向量分量中最大值
///
/// 源向量
/// 源向量
/// [输出属性] 最大向量
public static void Max(ref Vector2 value1, ref Vector2 value2, out Vector2 result)
{
result.X = (value1.X > value2.X) ? value1.X : value2.X;
result.Y = (value1.Y > value2.Y) ? value1.Y : value2.Y;
}
///
/// 在规定的范围内限定一个值
///
/// 需要限定的向量
/// 最小值
/// 最大值
/// 限定后的向量
public static Vector2 Clamp(Vector2 value1, Vector2 min, Vector2 max)
{
Vector2 vector;
float x = value1.X;
x = (x > max.X) ? max.X : x;
x = (x < min.X) ? min.X : x;
float y = value1.Y;
y = (y > max.Y) ? max.Y : y;
y = (y < min.Y) ? min.Y : y;
vector.X = x;
vector.Y = y;
return vector;
}
///
/// 在规定的范围内限定一个值
///
/// 需要限定的向量
/// 最小值.
/// 最大值.
/// [输出属性] 限定后的向量
public static void Clamp(ref Vector2 value1, ref Vector2 min, ref Vector2 max, out Vector2 result)
{
float x = value1.X;
x = (x > max.X) ? max.X : x;
x = (x < min.X) ? min.X : x;
float y = value1.Y;
y = (y > max.Y) ? max.Y : y;
y = (y < min.Y) ? min.Y : y;
result.X = x;
result.Y = y;
}
///
/// 执行两个向量之间的线性插值
///
/// 源向量
/// 源向量
/// 表明value2的权重,数字0到1之间
/// 两个向量之间的线性插值
public static Vector2 Lerp(Vector2 value1, Vector2 value2, float amount)
{
Vector2 vector;
vector.X = value1.X + ((value2.X - value1.X) * amount);
vector.Y = value1.Y + ((value2.Y - value1.Y) * amount);
return vector;
}
///
/// 执行两个向量之间的线性插值
///
/// 源向量
/// 源向量
/// 表明value2的权重,数字0到1之间
/// [输出属性] 两个向量之间的线性插值
public static void Lerp(ref Vector2 value1, ref Vector2 value2, float amount, out Vector2 result)
{
result.X = value1.X + ((value2.X - value1.X) * amount);
result.Y = value1.Y + ((value2.Y - value1.Y) * amount);
}
///
/// 用立方等式在两个值之间插值
///
/// 源向量
/// 源向量
/// 权重
/// 计算结果
public static Vector2 SmoothStep(Vector2 value1, Vector2 value2, float amount)
{
Vector2 vector;
amount = (amount > 1f) ? 1f : ((amount < 0f) ? 0f : amount);
amount = (amount * amount) * (3f - (2f * amount));
vector.X = value1.X + ((value2.X - value1.X) * amount);
vector.Y = value1.Y + ((value2.Y - value1.Y) * amount);
return vector;
}
///
/// 用立方等式在两个值之间插值
///
/// 源向量
/// 源向量
/// 权重
/// [输出属性] 计算结果
public static void SmoothStep(ref Vector2 value1, ref Vector2 value2, float amount, out Vector2 result)
{
amount = (amount > 1f) ? 1f : ((amount < 0f) ? 0f : amount);
amount = (amount * amount) * (3f - (2f * amount));
result.X = value1.X + ((value2.X - value1.X) * amount);
result.Y = value1.Y + ((value2.Y - value1.Y) * amount);
}
///
/// 返回一个指向相反方向的向量
///
/// 源向量
/// 指向相反方向的向量
public static Vector2 Negate(Vector2 value)
{
Vector2 vector;
vector.X = -value.X;
vector.Y = -value.Y;
return vector;
}
///
/// 返回一个指向相反方向的向量
///
/// 源向量
/// [输出属性] 指向相反方向的向量
public static void Negate(ref Vector2 value, out Vector2 result)
{
result.X = -value.X;
result.Y = -value.Y;
}
///
/// 计算两个向量的点积,如果两个向量是单位向量, 所得乘积是-1到1之间的浮点值 可以用来确定两个向量之间的一些夹角,例如, 它可以表明向量是否正交,平行,或者夹角是锐角还是钝角
///
/// 源向量
/// 源向量
/// 两个向量的点积
public static float Dot(Vector2 value1, Vector2 value2)
{
return ((value1.X * value2.X) + (value1.Y * value2.Y));
}
///
/// 计算两个向量的点积,如果两个向量是单位向量, 所得乘积是-1到1之间的浮点值 可以用来确定两个向量之间的一些夹角,例如, 它可以表明向量是否正交,平行,或者夹角是锐角还是钝角
///
/// 源向量
/// 源向量
/// [输出属性] 两个向量的点积
public static void Dot(ref Vector2 value1, ref Vector2 value2, out float result)
{
result = (value1.X * value2.X) + (value1.Y * value2.Y);
}
///
/// 返回向量之间的夹角
///
/// 源向量.
/// 源向量
/// [输出属性]向量之间夹角的角度值
public static float Angle(Vector2 from, Vector2 to)
{
from.Normalize();
to.Normalize();
float dot;
Vector2.Dot(ref from, ref to, out dot);
return (MathHelper.ACos(MathHelper.Clamp(dot, -1f, 1f)) * 57.29578f);
}
///
/// 返回向量之间的夹角
///
/// 源向量
/// 源向量
/// [输出属性] 向量之间夹角的角度值
public static void Angle(ref Vector2 from, ref Vector2 to, out float result)
{
from.Normalize();
to.Normalize();
float dot;
Vector2.Dot(ref from, ref to, out dot);
result = (MathHelper.ACos(MathHelper.Clamp(dot, -1f, 1f)) * 57.29578f);
}
///
/// 计算两个向量相加
///
/// 源向量
/// 源向量
/// 两个向量相加的和
public static Vector2 Add(Vector2 value1, Vector2 value2)
{
Vector2 vector;
vector.X = value1.X + value2.X;
vector.Y = value1.Y + value2.Y;
return vector;
}
///
/// 计算两个向量相加
///
/// 源向量
/// 源向量
/// [输出属性] 两个向量相加的和
public static void Add(ref Vector2 value1, ref Vector2 value2, out Vector2 result)
{
result.X = value1.X + value2.X;
result.Y = value1.Y + value2.Y;
}
///
/// 计算两个向量相减
///
/// 源向量
/// 源向量
/// 两个向量相减的差
public static Vector2 Sub(Vector2 value1, Vector2 value2)
{
Vector2 vector;
vector.X = value1.X - value2.X;
vector.Y = value1.Y - value2.Y;
return vector;
}
///
/// 计算两个向量相减
///
/// 源向量
/// 源向量
/// [输出属性] 两个向量相减的差
public static void Sub(ref Vector2 value1, ref Vector2 value2, out Vector2 result)
{
result.X = value1.X - value2.X;
result.Y = value1.Y - value2.Y;
}
///
/// 两个向量的分量对应相乘
///
/// 源向量
/// 源向量
/// 相乘的结果
public static Vector2 Multiply(Vector2 value1, Vector2 value2)
{
Vector2 vector;
vector.X = value1.X * value2.X;
vector.Y = value1.Y * value2.Y;
return vector;
}
///
/// 两个向量的分量对应相乘
///
/// 源向量
/// 源向量
/// [输出属性] 相乘的结果
public static void Multiply(ref Vector2 value1, ref Vector2 value2, out Vector2 result)
{
result.X = value1.X * value2.X;
result.Y = value1.Y * value2.Y;
}
///
/// 向量乘以一个标量值
///
/// 源向量
/// 标量值
/// 向量乘以一个标量值所得的乘积
public static Vector2 Multiply(Vector2 value1, float scaleFactor)
{
Vector2 vector;
vector.X = value1.X * scaleFactor;
vector.Y = value1.Y * scaleFactor;
return vector;
}
///
/// 向量乘以一个标量值
///
/// 源向量
/// 标量值
/// [输出属性] 向量乘以一个标量值所得的乘积
public static void Multiply(ref Vector2 value1, float scaleFactor, out Vector2 result)
{
result.X = value1.X * scaleFactor;
result.Y = value1.Y * scaleFactor;
}
///
/// 两向量的分量对应相除
///
/// 源向量
/// 除向量
/// 相除的结果
public static Vector2 Divide(Vector2 value1, Vector2 value2)
{
Vector2 vector;
vector.X = value1.X / value2.X;
vector.Y = value1.Y / value2.Y;
return vector;
}
///
/// 两向量的分量对应相除
///
/// 源向量
/// 除向量
/// [输出属性] 相除的结果
public static void Divide(ref Vector2 value1, ref Vector2 value2, out Vector2 result)
{
result.X = value1.X / value2.X;
result.Y = value1.Y / value2.Y;
}
///
/// 向量除以一个标量值
///
/// 源向量
/// 标量值
/// 向量除以一个标量值所得的向量
public static Vector2 Divide(Vector2 value1, float divider)
{
Vector2 vector;
float num = 1f / divider;
vector.X = value1.X * num;
vector.Y = value1.Y * num;
return vector;
}
///
/// 向量除以一个标量值
///
/// 源向量
/// 标量值
/// [输出属性] 向量除以一个标量值所得的向量.
public static void Divide(ref Vector2 value1, float divider, out Vector2 result)
{
float num = 1f / divider;
result.X = value1.X * num;
result.Y = value1.Y * num;
}
///
/// 返回一个指向相反方向的向量
///
/// 源向量
/// 返回一个指向相反方向的向量
public static Vector2 operator -(Vector2 value)
{
Vector2 vector;
vector.X = -value.X;
vector.Y = -value.Y;
return vector;
}
///
/// 判断向量是否相等
///
/// 源向量
/// 源向量
/// 如果相等返回true,不相等返回false
public static bool operator ==(Vector2 value1, Vector2 value2)
{
return ((value1.X == value2.X) && (value1.Y == value2.Y));
}
///
/// 判断向量是否不等
///
/// 源向量
/// 源向量
/// 如果不相等返回true,相等返回false
public static bool operator !=(Vector2 value1, Vector2 value2)
{
if (value1.X == value2.X)
{
return !(value1.Y == value2.Y);
}
return true;
}
///
/// 两个向量相加
///
/// 源向量
/// 源向量
/// 两个向量相加所得的和
public static Vector2 operator +(Vector2 value1, Vector2 value2)
{
Vector2 vector;
vector.X = value1.X + value2.X;
vector.Y = value1.Y + value2.Y;
return vector;
}
///
/// 两个向量相减
///
/// 源向量
/// 源向量
/// 两个向量相减所得的差
public static Vector2 operator -(Vector2 value1, Vector2 value2)
{
Vector2 vector;
vector.X = value1.X - value2.X;
vector.Y = value1.Y - value2.Y;
return vector;
}
///
/// 两个向量的分量分别相乘
///
/// 源向量
/// 源向量
/// 相乘的结果
public static Vector2 operator *(Vector2 value1, Vector2 value2)
{
Vector2 vector;
vector.X = value1.X * value2.X;
vector.Y = value1.Y * value2.Y;
return vector;
}
///
/// 向量乘以一个标量值
///
/// 源向量
/// 标量值
/// 向量乘以一个标量值所得的向量
public static Vector2 operator *(Vector2 value, float scaleFactor)
{
Vector2 vector;
vector.X = value.X * scaleFactor;
vector.Y = value.Y * scaleFactor;
return vector;
}
///
/// 向量乘以一个标量值
///
/// 标量值
/// 源向量
/// 向量乘以一个标量值所得的向量
public static Vector2 operator *(float scaleFactor, Vector2 value)
{
Vector2 vector;
vector.X = value.X * scaleFactor;
vector.Y = value.Y * scaleFactor;
return vector;
}
///
/// 两个向量的分量对应相除
///
/// 源向量
/// 除向量
/// 相除的结果
public static Vector2 operator /(Vector2 value1, Vector2 value2)
{
Vector2 vector;
vector.X = value1.X / value2.X;
vector.Y = value1.Y / value2.Y;
return vector;
}
///
/// 向量除以一个标量值
///
/// 源向量
/// 标量值
/// 向量除以一个标量值所得的向量
public static Vector2 operator /(Vector2 value1, float divider)
{
Vector2 vector;
float num = 1f / divider;
vector.X = value1.X * num;
vector.Y = value1.Y * num;
return vector;
}
static Vector2()
{
_zero = new Vector2();
_one = new Vector2(1f, 1f);
_unitX = new Vector2(1f, 0f);
_unitY = new Vector2(0f, 1f);
}
}
}