读书人

关于直线面化的算法解决思路

发布时间: 2012-03-12 12:45:32 作者: rapoo

关于直线面化的算法
谁能讲讲使一条直线被面化的算法是如何实现的,已知有一条直线的点列和直线面化后的宽度。
在线等待。

[解决办法]
这里有一个关于直线面化的代码,看看对你有没有帮助。

template<typename T>
static void
CalcLinePolygon(
const T*pPoints,// (I)
longlPointNum,// (I)
floatfWidth,// (I)
T*pPolygon,// (I)
long*plVertexNum
)
{
fWidth/= 2;

T*psFig= pPolygon;

// First Point
POINT sPos, sPos1;

shortsHeight= 0;

sPos.x= pPoints[0];
sPos.y= pPoints[1];

int idx = 1;
while(true) {
sPos1.x= pPoints[(idx * 2) + 0];
sPos1.y= pPoints[(idx * 2) + 1];

if((sPos.x == sPos1.x) && (sPos.y == sPos1.y)) {
idx++;
continue;
}

CVector2ddvec(calcDVec(sPos1, sPos));

dvec.x*=fWidth;
dvec.y*=fWidth;

// Create start circle start

CVector2dlvec(dvec.y * COS_30 * ASPECT_RATIO, -dvec.x * COS_30);
CVector2ddlvec(dvec.x * SIN_30 * ASPECT_RATIO, dvec.y * SIN_30);

sHeight= 0;

*psFig= RoundUp(pPoints[0] + (lvec.x - dlvec.x));
psFig+=1;
*psFig= RoundUp(pPoints[1] + (lvec.y - dlvec.y));
psFig+=1;
*psFig++= RoundUp(pPoints[0] + (lvec.x + dlvec.x));
psFig+=1;
*psFig= RoundUp(pPoints[1] + (lvec.y + dlvec.y));
psFig+=1;
*psFig= sHeight;
psFig+=1;
// Create start circle end

*psFig= RoundUp(pPoints[0] - dvec.x);
psFig+=1;
*psFig= RoundUp(pPoints[1] - dvec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;
*psFig= RoundUp(pPoints[0] + dvec.x);
psFig+=1;
*psFig= RoundUp(pPoints[1] + dvec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;

break;
}


POINTlast_pos = {pPoints[0], pPoints[1]};
POINTlPos0, lPos1, lPos2;
CVector2deVec01, eVec21, mVec, lVec, dVec;
doubleoutProduct, absOutProduct, dotProduct;
for ( int i = 1 ; i < lPointNum-1 ; ++i ) {
intidx1= i * 2;
//intidx0= idx1 - 2;// intidx0= (i - 1) * 2;
intidx2= idx1 + 2;// intidx2= (i + 1) * 2;

lPos1.x = pPoints[idx1 + 0];lPos1.y = pPoints[idx1 + 1];//POINTlPos1= {pPoints[idx1 + 0], pPoints[idx1 + 1]};
lPos2.x = pPoints[idx2 + 0];lPos2.y = pPoints[idx2 + 1];// POINTlPos2= {pPoints[idx2 + 0], pPoints[idx2 + 1]};

if(IsSamePoint(lPos1, last_pos)) {
continue;
}

lPos0 = last_pos;

intj = 0;
boolnothing = false;
for(j = 0; IsSamePoint(lPos1, lPos2); j++) {
if(i+j > lPointNum - 1) {
nothing = true;
break;
}
lPos2.x = pPoints[((i + j) * 2) + 0];
lPos2.y = pPoints[((i + j) * 2) + 1];
}

if(nothing) {
continue;
}

eVec01.x = lPos1.x - lPos0.x;eVec01.y = lPos1.y - lPos0.y;
eVec01.Normalize();

eVec21.x = lPos1.x - lPos2.x;eVec21.y = lPos1.y - lPos2.y;
eVec21.Normalize();

outProduct= (eVec21.x * eVec01.y) - (eVec21.y * eVec01.x);
absOutProduct= ((outProduct > 0.0) ? outProduct : -outProduct);

sHeight= 0;

if( absOutProduct < DBL_EPSILON ) {
dVec.x = eVec01.y * fWidth;
dVec.y = -eVec01.x * fWidth ;

*psFig= RoundUp(pPoints[idx1 + 0] - dVec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] - dVec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;

*psFig= RoundUp(pPoints[idx1 + 0] + dVec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] + dVec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;

last_pos= lPos1;
continue;
}

if(absOutProduct < SIN_60)// 0~45 135~225 315~360


{
dotProduct = (eVec01.x * eVec21.x) + (eVec01.y * eVec21.y);
if(dotProduct > COS_60)// 0~45 315~360
{
if(outProduct > 0.0f)
{
mVec.x = eVec01.x + eVec21.x;
mVec.y = eVec01.y + eVec21.y;

lVec.x =( -mVec.x * fWidth) / outProduct;
lVec.y = (-mVec.y * fWidth) / outProduct;

mVec.Normalize();
mVec.x *= fWidth;
mVec.y *= fWidth;

if(dotProduct > COS_15)// 0 ~ 15
{
CVector2d nVec01(lPos1.x - lPos0.x, lPos1.y - lPos0.y);
CVector2d nVec21(lPos1.x - lPos2.x, lPos1.y - lPos2.y);

double sqlVec= (lVec.x * lVec.x) + (lVec.y * lVec.y);
double sqnVec01= (nVec01.x * nVec01.x) + (nVec01.y * nVec01.y);
double sqnVec21= (nVec21.x * nVec21.x) + (nVec21.y * nVec21.y);
if((sqlVec > sqnVec01) || (sqlVec > sqnVec21))
{
double sqnVecMin = (sqnVec01 < sqnVec21) ? sqnVec01 : sqnVec21;

lVec.x*= (sqnVecMin / sqlVec);
lVec.y*= (sqnVecMin / sqlVec);
}
}

dVec.x = mVec.y;
dVec.y = -mVec.x;

// 0
*psFig= RoundUp(pPoints[idx1 + 0] + lVec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] + lVec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;
// 1
*psFig= RoundUp(pPoints[idx1 + 0] + dVec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] + dVec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;
// 2
*psFig= RoundUp(pPoints[idx1 + 0] + lVec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] + lVec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;
// 3
*psFig= RoundUp(pPoints[idx1 + 0] + mVec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] + mVec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;
// 4
*psFig= RoundUp(pPoints[idx1 + 0] + lVec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] + lVec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;
// 5
*psFig= RoundUp(pPoints[idx1 + 0] - dVec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] - dVec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;
}
else
{
mVec.x = eVec01.x + eVec21.x;
mVec.y = eVec01.y + eVec21.y;

lVec.x = (mVec.x * fWidth) / outProduct;
lVec.y = (mVec.y * fWidth) / outProduct;

mVec.Normalize();
mVec.x *= fWidth;
mVec.y *= fWidth;

if(dotProduct > COS_15)// 0 ~ 15
{
CVector2d nVec01(lPos1.x - lPos0.x, lPos1.y - lPos0.y);
CVector2d nVec21(lPos1.x - lPos2.x, lPos1.y - lPos2.y);

double sqlVec= (lVec.x * lVec.x) +( lVec.y * lVec.y);
double sqnVec01= (nVec01.x * nVec01.x) + (nVec01.y * nVec01.y);
double sqnVec21= (nVec21.x * nVec21.x) + (nVec21.y * nVec21.y);
if((sqlVec > sqnVec01) || (sqlVec > sqnVec21))
{
double sqnVecMin = (sqnVec01 < sqnVec21) ? sqnVec01 : sqnVec21;

lVec.x*= (sqnVecMin / sqlVec);
lVec.y*= (sqnVecMin / sqlVec);
}
}

dVec.x = -mVec.y;
dVec.y = mVec.x;

// 1
*psFig= RoundUp(pPoints[idx1 + 0] + dVec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] + dVec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;
// 0
*psFig= RoundUp(pPoints[idx1 + 0] + lVec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] + lVec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;
// 3
*psFig= RoundUp(pPoints[idx1 + 0] + mVec.x);


psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] + mVec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;
// 2
*psFig= RoundUp(pPoints[idx1 + 0] + lVec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] + lVec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;
// 5
*psFig= RoundUp(pPoints[idx1 + 0] - dVec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] - dVec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;
// 4
*psFig= RoundUp(pPoints[idx1 + 0] + lVec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] + lVec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;
}

last_pos= lPos1;
continue;
}
}

{
mVec.x = eVec01.x + eVec21.x;
mVec.y = eVec01.y + eVec21.y;

mVec.x *= (fWidth / outProduct);
mVec.y *= (fWidth / outProduct);

*psFig= RoundUp(pPoints[idx1 + 0] - mVec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] - mVec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;

*psFig= RoundUp(pPoints[idx1 + 0] + mVec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] + mVec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;
}

last_pos= lPos1;
}

// Last Point
intidx1= (lPointNum - 1) * 2;
sPos1.x= pPoints[idx1 + 0];
sPos1.y= pPoints[idx1 + 1];

idx = idx1 - 2;// idx= (lPointNum - 2) * 2;
while(true) {
sPos.x= pPoints[idx + 0];
sPos.y= pPoints[idx + 1];

if((sPos.x == sPos1.x) && (sPos.y == sPos1.y)) {
idx -= 2;
continue;
}

CVector2ddvec(calcDVec(sPos1, sPos));

dvec.x*= fWidth;
dvec.y*= fWidth;

sHeight= 0;

*psFig= RoundUp(pPoints[idx1 + 0] - dvec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] - dvec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;

*psFig= RoundUp(pPoints[idx1 + 0] + dvec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] + dvec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;

CVector2dlvec(-dvec.y * COS_30 * ASPECT_RATIO, dvec.x * COS_30);
CVector2ddlvec(dvec.x * SIN_30 * ASPECT_RATIO, dvec.y * SIN_30);

*psFig= RoundUp(pPoints[idx1 + 0] + lvec.x - dlvec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] + lvec.y - dlvec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;

*psFig= RoundUp(pPoints[idx1 + 0] + lvec.x + dlvec.x);
psFig+=1;
*psFig= RoundUp(pPoints[idx1 + 1] + lvec.y + dlvec.y);
psFig+=1;
*psFig= sHeight;
psFig+=1;

break;
}

*plVertexNum= (psFig - pPolygon) / 3;
}

读书人网 >VC/MFC

热点推荐