线段:
Vector3 direction() const
{
Vector3 dir = end - start;
dir.normalize();
return dir;
}
Vector3 Line::project(const Vector3 & point)
{
Vector3 n = direction(); //直线方向
Vector3 sp = point - start; //start -> point
float d = sp*n; //边sp在直线上的投影长度
Vector3 q = start + n*d; //投影点
return q;
}
bool Line::intersect(Vector3 & cross, const Line & line)
{
Vector3 n1 = direction();
Vector3 n2 = line.direction();
Vector3 n1xn2 = n1.cross(n2);
if (n1xn2.isZero()) //直线平行
{
return false;
}
float dn1xn2 = 1.0f/n1xn2.lengthSq();
Vector3 p1p2 = line.start - start;
float d1 = p1p2.cross(n2) * n1xn2 * dn1xn2;
float d2 = p1p2.cross(n1) * n1xn2 * dn1xn2;
Vector3 q1 = start + n1*d1;
Vector3 q2 = line.start + n2*d2;
if (q1.distToSq(q2) != 0.0f)
{
return false;
}
cross = q1;
return true;
}
点乘、叉乘
//点乘
float dot(const Vector3& v) const
{
return (*this) * v;
}
//差乘
Vector3 cross(const Vector3& v) const
{
Vector3 temp;
D3DXVec3Cross(&temp, this, &v);
return temp;
}
//差乘
void cross(Vector3 & out, const Vector3& v) const
{
D3DXVec3Cross(&out, this, &v);
}
转向行为2d向量
转向行为 2D向量类
package com
{
import flash.display.Graphics;
/**
* 一个2D向量类
*/
public class Vector2D
{
//向量的 x 轴
private var _x:Number;
//向量的 y 轴
private var _y:Number;
public function Vector2D(x:Number = 0, y:Number = 0)
{
_x = x;
_y = y;
}
/**
* 可用于可视化向量。一般只用于调试目的.
* @param graphics 用来绘制向量的Graphics实例.
* @param color 绘制向量的线条的颜色.
*/
public function draw(graphics:Graphics, color:uint = 0):void
{
graphics.lineStyle(0, color);
graphics.moveTo(0, 0);
graphics.lineTo(_x, _y);
}
/**
* 创建此向量的副本
* @return Vector2D 返回此向量的副本.
*/
public function clone():Vector2D
{
return new Vector2D(x, y);
}
/**
* 向量归零 设置向量的_x 和 _y 的值为0 同时向量的length 也受影响变成了0.
* @return Vector2D 返回调用此方法的向量.
*/
public function zero():Vector2D
{
_x = 0;
_y = 0;
return this;
}
/** 返回此向量是否归零 如果 _x和_y都是0 则返回true 否则返回false */
public function isZero():Boolean
{
return _x == 0 && _y == 0;
}
/** * 设置向量的长度. 改变长度将改变 向量的_x 和 _y 但不改变向量的角度 */
public function set length(value:Number):void
{
var a:Number = angle;
_x = Math.cos(a) * value; //从这个算法来看 _x 并不是向量的 X轴的长度 而是X轴的 坐标 那么 在数值上等同于X轴上的长度 看来 另一个点是 (0,0)点
_y = Math.sin(a) * value;
}
public function get length():Number
{
return Math.sqrt(lengthSQ);
}
/** *得到向量长度的平方结果 根据三角形勾股定理 X平方+Y平方=斜边平方 */
public function get lengthSQ():Number
{
return _x * _x + _y * _y;
}
/** *设置向量的角度. 改变角度将改变向量的 _x 和 _y 但不改变向量的长度 */
public function set angle(value:Number):void
{
var len:Number = length;
_x = Math.cos(value) * len; //根据长度 和角度 利用余弦计算长度
_y = Math.sin(value) * len; //根据长度 和角度 利用正选计算长度
}
public function get angle():Number
{
return Math.atan2(_y, _x);
}
/**
* 规范化这个向量。相当于设置长度为1 单位向量,但更有效率。
* @return Vector2D 返回调用此方法的向量实例 */
public function normalize():Vector2D
{
if(length == 0) //如果长度是0
{
_x = 1; //设置_x = 1 间接修改了 length = 1;
return this;
}
var len:Number = length;
_x /= len;
_y /= len; //_x _y 除等于 len 间接修改了 length =1
return this;
}
/**
* 确保向量的长度不超过给定的值.
* @param max 给定的值应该是这个向量的最大值.
* 如果当前向量长度大于max给定的值 将会把当前向量的长度修改成 max 给定的值
* @return Vector2D 返回调用此方法的向量.
*/
public function truncate(max:Number):Vector2D
{
length = Math.min(max, length);
return this;
}
/** *反转向量 */
public function reverse():Vector2D
{
_x = -_x;
_y = -_y;
return this;
}
/** 向量是否规范化 length==1 返回true 否则返回false */
public function isNormalized():Boolean
{
return length == 1.0;
}
/**
* 计算向量和另一个向量点乘. 待定
* @param v2 一个向量实例
* @return 返回点乘结果
*/
public function dotProd(v2:Vector2D):Number
{
return _x * v2.x + _y * v2.y;
}
/**
* 计算向量和另一个向量叉乘. 待定
* @param v2 一个向量实例
* @return 返回叉乘结果*/
public function crossProd(v2:Vector2D):Number
{
return _x * v2.y - _y * v2.x;
}
/**
* 计算两向量的夹角
* @param v1 The first Vector2D instance.
* @param v2 The second Vector2D instance.
* @return Number the angle between the two given vectors.
*/
public static function angleBetween(v1:Vector2D, v2:Vector2D):Number
{
if(!v1.isNormalized())
v1 = v1.clone().normalize();
if(!v2.isNormalized())
v2 = v2.clone().normalize();
return Math.acos(v1.dotProd(v2));
}
/**
* 判断一个向量是在这个向量的左边还是右边.
* @return int If to the left, returns -1. If to the right, +1.
*/
public function sign(v2:Vector2D):int
{
return perp.dotProd(v2) < 0 ? -1 : 1;
}
/**
* 创建一个垂直这个向量的向量
* @return 返回一个向量
*/
public function get perp():Vector2D
{
return new Vector2D(-y, x);
}
/**
* 计算两个向量之间的距离.
* @param v2 一个向量实例.
* @return 两个向量之间的距离.
*/
public function dist(v2:Vector2D):Number
{
return Math.sqrt(distSQ(v2));
}
/**
* 计算两个向量之间距离的平方.
* @param v2 一个向量实例.
* @return 返回两个向量之间的平方.
*/
public function distSQ(v2:Vector2D):Number
{
var dx:Number = v2.x - x;
var dy:Number = v2.y - y;
return dx * dx + dy * dy;
}
/**
* 向量 相加 创建一个新的向量来保存结果.
* @param v2 一个Vector2D 向量实例.
* @return 返回一个新的向量.
*/
public function add(v2:Vector2D):Vector2D
{
return new Vector2D(_x + v2.x, _y + v2.y);
}
/**
* 向量 相减 创建一个新的向量来保存结果.
* @param v2 一个Vector2D 向量实例.
* @return 返回一个新的向量.
*/
public function subtract(v2:Vector2D):Vector2D
{
return new Vector2D(_x - v2.x, _y - v2.y);
}
/**
* 向量乘以一个值,创建一个新的Vector2D实例来保存结果.
* @param v2 一个向量实例.
* @return 返回一个向量.
*/
public function multiply(value:Number):Vector2D
{
return new Vector2D(_x * value, _y * value);
}
/**
* 向量除以一个值,创建一个新的Vector2D实例来保存结果.
* @param v2 一个向量实例.
* @return 返回一个向量.
*/
public function divide(value:Number):Vector2D
{
return new Vector2D(_x / value, _y / value);
}
/**
* 判断连个向量是否相等.
* @param v2 一个向量实例
* @return Boolean True if the other vector is equal to this one, false if not.
*/
public function equals(v2:Vector2D):Boolean
{
return _x == v2.x && _y == v2.y;
}
/** * Sets / gets the x value of this vector. */
public function set x(value:Number):void
{
_x = value;
}
public function get x():Number
{
return _x;
}
/** * Sets / gets the y value of this vector. */
public function set y(value:Number):void
{
_y = value;
}
public function get y():Number
{
return _y;
}
public function toString():String
{
return "[Vector2D (x:" + _x + ", y:" + _y + ")]";
}
}
}
#flash #flex