⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 geometry.h

📁 2002年
💻 H
字号:
#ifndef __GEOMETRY_H__
#define __GEOMETRY_H__


#include "smp_datastruct.h"


/********************************************************************************/
/*                        Vector Class                                          */
/********************************************************************************/
inline Vector Polar2Vector(float dist, float ang) {
	return Vector(dist * Cos(ang), dist * Sin(ang));
}

inline Vector bisector(Vector a, Vector b){
	a.Normalize();
	b.Normalize();
	Vector c = a + b;
	c.Normalize();
	return c;
}

/********************************************************************************/
/*                       Ray Class                                              */
/********************************************************************************/
class Line;
class Ray 
{
public:
	Ray(){ origin = Vector(0,0); direction = Vector(1,0); angle = 0;}
	Ray(const Vector& orig, float ang){
		origin = orig;
		direction = Polar2Vector(1.0, ang);
		angle = ang;
	}
	Ray(const Vector& orig, const Vector& dir){
		origin = orig;
		direction = dir;
		direction.Normalize();
		angle = direction.Angle();
	}
	
	float Dir() const{ return angle;}
	void SetValues(const Vector& orig, float ang){
		origin = orig; 
		direction = Polar2Vector(1.0, ang); 
		angle = ang; 
	}
	void SetValues(const Vector& orig, const Vector& dir){
		origin = orig; 
		direction = dir; 
		direction.Normalize();
		angle = dir.Angle();
	}

	bool OnRay(const Vector& point) const;//point on the ray
	bool InRightDir(const Vector&  point) const; // more lenient than above about distance off ray 
	bool InRightDir(float angle) const;
	bool InOppositeDir(const Vector&  point) const; // more lenient than above about distance off ray 
	bool InOppositeDir(float angle) const;		
	float Allowed_AngleDiff(float distance = 5.0f) const;//default the distance is 5.0f
	float Allowed_AngleDiff(const Vector&  point) const;
	bool intersection(const Ray& r, Vector&pPt) const;//intersection with ray
	bool intersection(const Line& l, Vector&pPt) const;//intersection with line
	float intersection(const Line& l) const;//get the normalized param of the intersection point

	Vector GetPoint(float dist) const{ return origin + direction * dist;}
	/*	intersect with circle	*/
	int CircleIntersect(float radius, const Vector& center, Vector& psol1, Vector& psol2) const;

	/*	get strechangle	*/
	float StrechAngle(const Vector& point) const;
	float DistanceFromOrigin(const Vector& point) const;

	Vector GetClosestPoint(const Vector& point) const;

	float GetClosestPointParam(const Vector& point) const; // return param t, origin + direction * t = closest_point 

	void Normalize();

	friend class Line;

protected:
	Vector origin;
	Vector direction;
	float  angle;
};

/********************************************************************************/
/*                      Line Class                                              */
/********************************************************************************/
class Line {
private:	
    /* Ax + By + C = 0 */
public:
	float A,B,C;
	Line(float A = 0.0, float B = 0.0, float C = 0.0);
	Line(const Ray& r) { LineFromRay(r); }
	/*	initialize a line from two points	*/
	void LineFromTwoPoints(const Vector& pt1, const Vector& pt2);
	/*	initialize a line from a ray	*/
	void LineFromRay(const Ray& r);
	/*	initialize a line from an origin and direction	*/
	void LineFromRay(const Vector& orig, float dir){
		LineFromRay(Ray(orig, dir));
	}
	void LineFromRay(const Vector& orig, const Vector& dir){
		LineFromRay(Ray(orig, dir)); 
	}
	void LineFrompline(const Vector& pos1, const Vector& pos2){
		A = 2* (pos2.x - pos1.x); 
		B = 2 *(pos2.y - pos1.y); 
		C= pos1.x * pos1.x - pos2.x * pos2.x + pos1.y * pos1.y - pos2.y* pos2.y;
	}
  
	/*	Is the point on the line	*/
	bool PointOnLine(float x, float y) const;
	inline bool PointOnLine(const Vector& point) const{
		return PointOnLine(point.x, point.y); 
	}

	/*	distance between the point and the line	*/
	float dist(const Vector& point) const;
	float dist2(const Vector& point) const;
	float angle() const; /* returns the angle of the line in [-90, 90] */
  
	/*	Is the point between end1 and end2	*/
	bool InBetween(const Vector& pt, const Vector& end1, const Vector& end2) const;
	/*	Get the closest point on the line which is between end1 and end2	*/
	Vector GetClosestPtInBetween(const Vector& pt, const Vector& end1, const Vector& end2) const;
  
	/*	more lenient than pointonline	*/
	inline bool OnLine(const Vector& point, float allowance = 1.0) const{
		return bool(dist2(point) < Sqr(allowance));
	}
  
	/*	Get Project Point	*/
	inline Vector ProjectPoint(const Vector& point) const{ return intersection(perpendicular(point)); }

	/*	get y given x	*/
	float get_y(float x) const;
	/*	get x given y	*/
	float get_x(float y) const;
	/*	intersection with a line	*/
	Vector intersection(const Line& l) const;

	/*	Is the ray intersected with the line	*/
	bool RayIntersection(const Ray& r, Vector& ppt) const;
	/*	Intersection with a circle	*/
	int CircleIntersect(float radius, const Vector& center, Vector& psol1, Vector& psol2) const;
	
	/*	get perpendicular line from a point	*/
	inline Line perpendicular(const Vector& point) const{ 
		return Line(B,-A,A*point.y - B*point.x);
	}

	Line shift_y(float t) const{ return Line(A, B, C - t * B); }
	Line shift_x(float t) const{ return Line(A, B, C - t * A); }  

  /* returns whether the projection of pt1 is closer to targ_pt than the
     projection of pt2 */
	bool IsPtCloserToPtOnLine(const Vector& pt1, const Vector& pt2, const Vector& targ_pt) const;
  
	bool HalfPlaneTest(const Vector& pt) const; //return true on top/left part of plane
	bool SameSlope(const Line& l) const;

	friend class Ray;
} ;

/********************************************************************************/
/*                      Class Rect                                         */
/********************************************************************************/
class Rect {
private:
	float left_x ;
	float right_x ;
	float top_y ;
	float bottom_y ;
public:
	Vector Center() const;

	Rect() ;
	Rect(float left,float right, float top, float bottom) ;
	Rect(const Vector& center, const Vector& size) ;
		  
	inline float TopY()		const{ return top_y; }
	inline float BottomY()	const{ return bottom_y; }
	inline float RightX()	const{ return right_x; }
	inline float LeftX()	const{ return left_x; }

	inline Vector TopLeftCorner() const{ return Vector(left_x, top_y); }
	inline Vector TopRightCorner() const{ return Vector(right_x, top_y); }
	inline Vector BottomLeftCorner() const{ return Vector(left_x, bottom_y); }
	inline Vector BottomRightCorner() const{ return Vector(right_x, bottom_y); }

	Vector GetPoint(int n)  const; //order: TL, TR, BR, BL; starting at 0
	inline float Width() const{ return right_x - left_x; }   
	inline float Height() const{ return bottom_y - top_y; }  
	bool   IsWithin(const Vector& p) const;

	Line LeftEdge() const;
	Line RightEdge() const;
	Line TopEdge() const;
	Line BottomEdge() const;

	Line nearestHEdgeLine(const Vector& p) const;
	Line nearestVEdgeLine(const Vector& p) const;
	Line nearestEdgeLine(const Vector& p) const;
	bool RayIntersection(const Ray& r,Vector &p) const;
} ;

/********************************************************************************/
/*                      The3rdCurve                                             */
/********************************************************************************/
class The3rdCurve{
private:
	float a, b, c, d;
	float inf, sup;
public:
	The3rdCurve(float a = 0.0f, float b = 0.0f, float c = 0.0f, float d = 0.0f, float inf = 0.0f, float sup = 1.0f);
	bool Interpolation(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3);
	float GetOutput(float x, bool limited = true) const;
	void SetABCD(float a, float b, float c, float d);
	void  SetInfSup(float inf, float sup);
};

/********************************************************************************/
/*                      Ring Sector                                             */
/********************************************************************************/
struct NoiseData{
	float mean;
	float delta;
	NoiseData(){};
	NoiseData(float m, float d){ mean = m; delta = d;}

	float sup() const{return mean + delta;}
	float inf() const{return mean - delta;}
	
	bool IsWithin(float x){return fabs(x-mean) <= delta;}
	bool Intersect(const NoiseData &data){//get the intersection of two noisedata
		float _sup = Min(sup(), data.sup());
		float _inf = Max(inf(), data.inf());
		mean = (_sup + _inf)/2;
		delta = (_sup - _inf)/2;
		return bool(delta>=0);
	}
};

struct NoiseVector{
	Vector mean;
	float delta;
	NoiseVector(){}
	NoiseVector(float x, float y, float delta){
		mean.x = x;	mean.y = y;	this->delta = delta;
	}
	NoiseVector(const Vector& value, float delta){
		mean = value;
		this->delta = delta;
	}
};

const int Max_ring_sector_angles = 3;
class RingSector{
private:
	bool valid;
public:
	NoiseData radius;
	Index<NoiseData, Max_ring_sector_angles> angles;

	//to determine whether a specific angle is in PossSpace angle section
	bool IsWithin(float angle);
	bool IsWithin(float angle, float dist);
	inline bool IsValid() const{return valid;}
	inline void ForceInValid(){valid = false;}
	
	RingSector(){
		valid = false;
	}
	void Set(float radius, float dradius, float angle, float dangle){
		this->radius.mean = radius; this->radius.delta = dradius;
		this->angles.Reset();
		this->angles.Add(NoiseData(angle, dangle));
		valid = true;
	}

	///space became larger as time goes by
	void Diffuse(int time=1, float speed=1.0f);
	//static void CombineSector(NoiseData& src, NoiseData& 
	
	//sight infor may diminish the PossSpace
	void MinusAngle(NoiseData& subtrahend);
	//sight infor may diminish the PossSpace
	void MinusRadius(float inf, float sup = 100.0f);
	
	//convert angle section from begin end form to noisedata form
	//'end' must lager than 'begin'
	static NoiseData CreateAngleSector(float begin ,float end){
		NoiseData nd;
		nd.delta = NormalizeAngle(end - begin, 0)/2;
		nd.mean =  NormalizeAngle(begin + nd.delta);
		return nd;
	}

	//Perceptron::sensory infor may diminish the PossSpace
	void Intersect(NoiseData r, NoiseData a);
	void operator = (const RingSector &ps);

	///angle space should change as my movement exist
	void ShiftCenter(const Vector& delta);
	
	///calculate angle confidence
	/*float GetAngleConf(float ang){//get the possibility the player is in this angle
		if (InSpace(ang)||InSpace(ang-360.0f)||InSpace(ang+360.0f))
			return ClientParam::division/(2*da);
		else return 0.0f;
	}*/

	///calculate area  
	float GetArea();
	//calculate center pos
	Vector GetCenterPos();
	
	float Getmax_x();
	float Getmin_x();

	inline float Dist(const Vector& pos){return Dist(pos.Angle(), pos.mod());}
	float Dist(float angle, float dist);

	bool Isthrough(const Vector& pos){return Isthrough(pos.Angle(), pos.mod());}
	bool Isthrough(float angle, float dist);
};

#endif //__GEOMETRY_H__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -