#include "myglbase.h"
#include "glut.h"
#include "vector"
#include "iostream"
using namespace std;
class Line2Segment
{
public:
Point2 first ;
Point2 second ;
Vector2 norm()
{
Vector2 c = second - first ;
Vector2 normalVector = c.GetNormalVector();
return normalVector;
}
Line2Segment()
{
first.x=first.y=0;
second.x=second.y=0;
}
Line2Segment(Point2 first,Point2 second)
{
this->first = first;
this->second = second;
}
Line2Segment(Line2Segment& line2)
{
first = line2.first;
second = line2.second;
}
};
class Line2
{
public:
Point2 pt ;
Vector2 norm;
Line2()
{
pt.x=pt.y=0;
norm.x=0;
norm.y=0;
}
Line2(Point2 pt,Vector2 norm)
{
this->pt=pt;
this->norm=norm;
}
Line2(const Line2& line2)
{
pt=line2.pt;
norm = line2.norm;
}
};
class Line2List
{
public:
vector<Line2> line;
int num()
{
return line.size();
}
void push_back(Line2 newLine)
{
line.push_back(newLine);
}
Line2& operator[](int index)
{
if ((unsigned int)index >= line.size()) //注意size是unsigned int
{
throw "Out of range in Line2List";
}
return line[index];
}
};
int chopCI(double&tIn,double&tOut,double number,double denom)
{
double tHit ;
if(denom < 0) //射线是射入
{
tHit = number / denom ;
if (tHit > tOut)
{
return 0 ;
}
else if(tHit>tIn)
{
tIn = tHit;
}
}
else if(denom > 0)
{
tHit = number / denom;
if (tHit<tIn)
{
return 0 ;
}
if (tHit<tOut)
{
tOut = tHit;
}
}
else if(number<=0) //denom为0,射线与直线平行
{
return 0 ; //在外半空间
}
return 1;
}
//线段和凸多边形的交点 (二维)
int CyrusBeckClip(Line2Segment& seg,Line2List& L)
{
double number,denom;
double tIn = 0.0,tOut = 1.0 ; //候选区间为[0,1]
Vector2 c, tmp ;
c = seg.first-seg.second; //直线的参数表示 R(t)=A+c*tHit
for (int i=0;i<L.num();i++)
{
//利用公式 tHit=n*(B-A)/(n*c) 其中A和c是目的直线参数表示,B和n是另一条直线点法向量
tmp = L.line[i].pt - seg.first;
number = L.line[i].norm * tmp ;
denom = L.line[i].norm * c ;
if (!chopCI(number,denom,tIn,tOut))
{
return 0 ; //提前结束
}
}
//注意tIn和tOut都是基于A+c*tHit ;所以在计算seg截点时,先计算seg.second;
//否则,A的值,即seg.first就变化了
if(tOut <1.0)
{
//书上做法
// seg.second.x = seg.first.x + c.x * tOut ;
// seg.second.y = seg.first.y + c.y * tOut ;
//我已经对操作符进行了重载了
seg.second = seg.first + c * tOut;
}
if (tIn>0.0)
{
//书上做法
// seg.first.x = seg.first.x + c.x * tIn ;
// seg.first.y = seg.first.y + c.y * tIn ;
//我已经对操作符重载
seg.first = seg.first + c * tIn;
}
return 1;
}
int main()
{
return 0 ;
}