📄 geometry.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 + -