夾點getGripPoints/moveGripPointsAt/捕捉點getOsnapPoints

已知圓外一點,以及圓心半徑,求圓的切點:app

方法1:ide

(b-y/a-x)*(n-y/m-x)=-1
(a-x)平方+(b-y)平方=r平方
聯立方程組求解

方法1:3d

CPoint CalcQieDian(CPoint ptCenter, CPoint ptOutside, double dbRadious) 
{ 
 struct point {double x, y;};
 point E,F,G,H;
 double r=dbRadious;
 //1. 座標平移到圓心ptCenter處,求園外點的新座標E
 E.x= ptOutside.x-ptCenter.x;
 E.y= ptOutside.y-ptCenter.y; //平移變換到E

 //2. 求園與OE的交點座標F, 至關於E的縮放變換
 double t= r / sqrt (E.x * E.x + E.y * E.y);  //獲得縮放比例
 F.x= E.x * t;   F.y= E.y * t;   //縮放變換到F

 //3. 將E旋轉變換角度a到切點G,其中cos(a)=r/OF=t, 因此a=arccos(t);
 double a=acos(t);   //獲得旋轉角度
 G.x=F.x*cos(a) -F.y*sin(a);
 G.y=F.x*sin(a) +F.y*cos(a);    //旋轉變換到G

 //4. 將G平移到原來的座標下獲得新座標H
 H.x=G.x+ptCenter.x;
 H.y=G.y+ptCenter.y;             //平移變換到H

 //5. 返回H
 return CPoint(int(H.x),int(H.y));
 //6. 實際應用過程當中,只要一箇中間變量E,其餘F,G,H能夠不用。
}

方法3:code

int _tmain(int argc, _TCHAR* argv[])
{
double m = 2, n = 0;
double a = 0, b = 0;
double r = 1;

cout << "請輸入圓心座標:";
cin >> a >> b;
cout << "請輸入半徑:";
cin >> r;
cout << "請輸入點座標:";
cin >> m >> n;
// 點到圓心距離的平方
double d2 = ( m - a ) * ( m - a ) + ( n - b ) * ( n - b );
// 點到圓心距離
double d = sqrt( d2 );
// 半徑的平方
double r2 = r * r;
if ( d2 < r2 )
{
cout << "點在圓內,無切點" << endl;
}
else if ( d2 == r2 )
{
cout << "點在圓上,切點爲給定點:(" << m <<
", " << n << ")" << endl;
}
else
{
// 點到切點距離
double l = sqrt( d2 - r2 );
// 點->圓心的單位向量
double x0 = ( a - m ) / d;
double y0 = ( b - n ) / d;
// 計算切線與點心連線的夾角
double f = asin( r / d );
// 向正反兩個方向旋轉單位向量
double x1 = x0 * cos( f ) - y0 * sin( f );
double y1 = x0 * sin( f ) + y0 * cos( f );
double x2 = x0 * cos( -f ) - y0 * sin( -f );
double y2 = x0 * sin( -f ) + y0 * cos( -f );
// 獲得新座標
x1 = ( x1 + m ) * l;
y1 = ( y1 + n ) * l;
x2 = ( x2 + m ) * l;
y2 = ( y2 + n ) * l;
cout << "點在圓外,切點有兩個:(" << x1 << ", "
<< y1 << ")和(" << x2 << ", " << y2 << ")" << endl;
}

system( "pause" );
return 0;
}

方法4:orm

struct vect
{
	double dbX;
	double dbY;

	vect() {}

	vect(double x, double y)
	{
		dbX = x;
		dbY = y;
	}

	double len()
	{
		return sqrt(dbX*dbX + dbY * dbY);
	}

	vect rotate1(double cosF, double sinF)
	{
		double dbVectorLen = len();
		double sinA = dbY / dbVectorLen;
		double cosA = dbX / dbVectorLen;
		vect result;
		result.dbX = dbVectorLen * ((cosA * cosF) - (sinA * sinF));
		result.dbY = dbVectorLen * ((cosA * sinF) + (sinA * cosF));
		return result;
	}

	vect rotate2(double cosF, double sinF)
	{
		double dbVectorLen = len();
		double sinA = dbY / dbVectorLen;
		double cosA = dbX / dbVectorLen;
		vect result;
		result.dbX = (dbX* cosF) - (dbY * sinF);
		result.dbY = (dbX * sinF) + (dbY * cosF);
		return result;
	}

	//把vector變成指定長度的向量
	void Normalize(double dbLen)
	{
		if (dbLen <= 0) return;
		double dbVectorLen = len();
		if (dbVectorLen == 0)return;
		dbX = dbX * dbLen / dbVectorLen;
		dbY = dbY * dbLen / dbVectorLen;
	}
	
};

struct Point
{
	double x;
	double y;
};

// 圓心x  外點 半徑  切點p1 切點p 2
void GetVector(double dbCenterX, double dbCenterY, double dbOutX, double dbOutY, double rad, Point& p1, Point& p2)
{
	//圓心o 到外點p 切點q 其中oq的長度爲半徑的長度
	vect op(dbOutX - dbCenterX, dbOutY - dbCenterY);
	double opLen = op.len();
	double pqLen = sqrt((opLen * opLen) - (rad * rad));	//算出切線長度

	//算出夾角 qop 這個夾角能夠爲正負
	double cosA = rad / opLen;
	double sinA = pqLen / opLen;

	//長度變爲半徑的向量
	op.Normalize(rad);
	//
	auto res1 = op.rotate2(cosA, sinA);
	//而後圓心
	//結果1就是
	p1.x = res1.dbX + dbCenterX;
	p1.y = res1.dbY + dbCenterY;
	//
	auto res2 = op.rotate2(cosA, -sinA);
	//而後圓心
	//結果2就是
	p2.x = res2.dbX + dbCenterX;
	p2.y = res2.dbY + dbCenterY;
}

開始正題:ip

圓弧:ci

OdResult CMdEdArcGripPointsEx::getGripPoints(
    const OdDbEntity* pEntity,
    OdDbGripDataPtrArray& grips,
    const double curViewUnitSize,
    const int gripSize,
    const OdGeVector3d& curViewDir,
    const int bitFlags ) const
{
    OdDbArc* pArc = OdDbArc::cast(pEntity);
    if(pArc == NULL)
    {
        return eOk;
    }

    OdGePoint3d centerPoint = pArc->center();
	OdGePoint3d startPoint,endPoint;
    pArc->getStartPoint(startPoint);
    pArc->getEndPoint(endPoint);

	OdGeVector3d vecChord = startPoint - endPoint;
	OdGeVector3d vecNormal = pArc->normal();
	OdGeVector3d vecCenter2Mid = vecNormal.crossProduct(vecChord);
	OdGeLine3d geLine(centerPoint, vecCenter2Mid);
	OdGeCircArc3d geArc(pArc->center(), pArc->normal(), OdGeVector3d::kXAxis, pArc->radius(), pArc->startAngle(), pArc->endAngle());
	
	int nNum = 0;
	OdGePoint3d midPoint;
	OdGePoint3d ptTemp;
	if(geArc.intersectWith(geLine, nNum, midPoint, ptTemp))
	{
		if (geArc.isOn(ptTemp))
			midPoint = ptTemp;
	}

    OdDbGripData* pGripData = NULL;

	pGripData = new OdDbGripData;
	pGripData->setAppData((void*)kCenterPoint);
	pGripData->setGripPoint(centerPoint);
	grips.append(pGripData);

	pGripData = new OdDbGripData;
	pGripData->setAppData((void*)kStartPoint);
	pGripData->setGripPoint(startPoint);
	grips.append(pGripData);

	pGripData = new OdDbGripData;
	pGripData->setAppData((void*)kEndPoint);
	pGripData->setGripPoint(endPoint);
	grips.append(pGripData);

	pGripData = new OdDbGripData;
	pGripData->setAppData((void*)kMidPoint);
	pGripData->setGripPoint(midPoint);
	grips.append(pGripData);

    return eOk;
}

OdResult CMdEdArcGripPointsEx::moveGripPointsAt(
    OdDbEntity* pEntity,
    const OdDbVoidPtrArray& grips,
    const OdGeVector3d& offset,
    int bitFlags )
{
    OdDbArcPtr pArc = OdDbArc::cast(pEntity);

    for (int i=0;i<(int)grips.size();i++)
    {
        OdDbGripData* pGripData = (OdDbGripData*)grips.at(i);

        switch ((int)pGripData->appData())
        {
        case kStartPoint:
            {
                OdGeMatrix3d mat;
                mat.setTranslation(offset);
                pArc->transformBy(mat);
            }
            break;
        case kCenterPoint:
            {
                OdGeMatrix3d mat;
                mat.setTranslation(offset);
                pArc->transformBy(mat);
            }
            break;
        case kMidPoint:
            {
                OdGePoint3d ptStart,ptEnd;
                pArc->getStartPoint(ptStart);
                pArc->getEndPoint(ptEnd);
                OdGePoint3d ptQuadBef = pGripData->gripPoint();
                OdGePoint3d ptQuadAft = ptQuadBef + offset;
                
                OdGeCircArc3d arc(ptStart,ptQuadAft,ptEnd);
                OdGePoint3d ptcenter = arc.center();
                double dRadius = arc.radius();
                double dStartAngle = arc.startAng();
                double dEndAngle = arc.endAng();
                pArc->setCenter(ptcenter);
                pArc->setRadius(dRadius);
//                 pArc->setEndAngle(dEndAngle);
//                 pArc->setStartAngle(dStartAngle);
            }
            break;
        case kEndPoint:
            {
                OdGeMatrix3d mat;
                mat.setTranslation(offset);
                pArc->transformBy(mat);
            }
            break;
        default:
            break;
        }
    }

    return eOk;
}

OdResult CMdEdArcGripPointsEx::getOsnapPoints( 
    const OdDbEntity* pEntity, 
    OdDb::OsnapMode osnapMode, 
    OdGsMarker gsSelectionMark, 
    const OdGePoint3d& pickPoint,
    const OdGePoint3d& lastPoint, 
    const OdGeMatrix3d& xWorldToEye, 
    OdGePoint3dArray& snapPoints ) const
{
	OdDbArc* pArc = OdDbArc::cast(pEntity);
	if(pArc == NULL)
	{
		return eOk;
	}

	OdGePoint3d ptOsnap; 
	switch(osnapMode)
	{
	case OdDb::kOsModeEnd:
		{
			OdGePoint3d tempPoint;
			pArc->getStartPoint(ptOsnap);
			pArc->getEndPoint(tempPoint);
			if (pickPoint.distanceTo(ptOsnap) > pickPoint.distanceTo(tempPoint))
				ptOsnap = tempPoint;

			snapPoints.append(ptOsnap);
			break;
		}
	case OdDb::kOsModeMid:
		{
			OdGePoint3d startPoint,endPoint,centerPoint;
			pArc->getStartPoint(startPoint);
			pArc->getEndPoint(endPoint);
			centerPoint = pArc->center();
			OdGeVector3d vecChord = startPoint - endPoint;
			OdGeVector3d vecNormal = pArc->normal();
			OdGeVector3d vecCenter2Mid = vecNormal.crossProduct(vecChord);
			OdGeLine3d geLine(centerPoint, vecCenter2Mid);
			OdGeCircArc3d geArc(centerPoint, pArc->normal(), OdGeVector3d::kXAxis, pArc->radius(), pArc->startAngle(), pArc->endAngle());

			int nNum = 0;
			OdGePoint3d midPoint;
			OdGePoint3d ptTemp;
			if(geArc.intersectWith(geLine, nNum, midPoint, ptTemp))
			{
				if (geArc.isOn(ptTemp))
					midPoint = ptTemp;
			}
			snapPoints.append(ptOsnap);
			break;
		}
	case OdDb::kOsModeCen:
		snapPoints.append(pArc->center());
		break;
	case OdDb::kOsModeNode:
		break;
	case OdDb::kOsModeQuad:
		{
			OdGePoint3d centerPoint = pArc->center();
			double dRadius = pArc->radius();
			OdGeVector3d vect1 = dRadius * OdGeVector3d::kXAxis;
			OdGeVector3d vect2 = dRadius * OdGeVector3d::kYAxis;

			OdGePoint3d ptOsnap = centerPoint + vect1;
			OdGePoint3d ptTemp = centerPoint - vect1;
			if (pickPoint.distanceTo(ptOsnap) > pickPoint.distanceTo(ptTemp))
				ptOsnap = ptTemp;

			ptTemp = centerPoint + vect2;
			if (pickPoint.distanceTo(ptOsnap) > pickPoint.distanceTo(ptTemp))
				ptOsnap = ptTemp;

			ptTemp = centerPoint - vect2;
			if (pickPoint.distanceTo(ptOsnap) > pickPoint.distanceTo(ptTemp))
				ptOsnap = ptTemp;

			snapPoints.append(ptOsnap);
			break;
		}
	case OdDb::kOsModeIntersec:
		break;
	case OdDb::kOsModePerp:
		{
			OdGePoint3d ptArc = pArc->center();
			OdGeLine3d line3d(ptArc,lastPoint);   
			OdGeCircArc3d arc(ptArc,pArc->normal(),pArc->radius());
			OdGePoint3d ptOsnap,ptTemp;
			int nNum = 0;
			if (arc.intersectWith(line3d,nNum,ptOsnap,ptTemp))
			{
				if (pickPoint.distanceTo(ptOsnap) > pickPoint.distanceTo(ptTemp))
					ptOsnap = ptTemp;
			}
			snapPoints.append(ptOsnap);
		}
		break;
	case OdDb::kOsModeTan:
		{
			OdGePoint3d ptCenter = pArc->center();
			double dRadius = pArc->radius();
			double dLastToCenter = lastPoint.distanceTo(ptCenter);//圓外一點到圓心距離
            if (OdZero(dLastToCenter))
            {
                return eOk;
            }
            double dcos = dRadius/dLastToCenter;
            if (dcos > 1.0)
            {
                return eOk;
            }
			double dAngle = acos(dcos);

			//旋轉圓外一點到圓心的直線
			OdGeVector3d vecCenterToLast = ptCenter - lastPoint;
			OdGeVector3d vecRadius1 =  vecCenterToLast.rotateBy(dAngle,pArc->normal());
			vecRadius1.normalize() * dRadius;

			OdGeVector3d vecRadius2 =  vecCenterToLast.rotateBy(-dAngle,pArc->normal());
			vecRadius2.normalize() * dRadius;
			
			//判斷是否在圓弧上
			OdGeCircArc3d geArc(ptCenter, pArc->normal(), OdGeVector3d::kXAxis, pArc->radius(), pArc->startAngle(), pArc->endAngle());
			if (geArc.isOn(ptCenter - vecRadius1) && !geArc.isOn(ptCenter - vecRadius2))
				ptOsnap = ptCenter - vecRadius1;
			else if (!geArc.isOn(ptCenter - vecRadius1) && geArc.isOn(ptCenter - vecRadius2))
				ptOsnap = ptCenter - vecRadius2;
			else if (geArc.isOn(ptCenter - vecRadius1) && geArc.isOn(ptCenter - vecRadius2))
			{
				ptOsnap = ptCenter - vecRadius1;
				OdGePoint3d ptTemp = ptCenter - vecRadius2;
				if (pickPoint.distanceTo(ptOsnap) > pickPoint.distanceTo(ptTemp))
					ptOsnap = ptTemp;
			}
			
			snapPoints.append(ptOsnap);
			break;
		}
	case OdDb::kOsModeNear:
		{
            /*
			OdGeCircArc3d arc(pArc->center(),pArc->normal(),pArc->radius());
			OdGePointOnCurve3d tmpPt;
			arc.getClosestPointTo(pickPoint,tmpPt);
			ptOsnap=tmpPt.point();
			snapPoints.append(ptOsnap);
            */
			break;
		}
	case OdDb::kOsModeApint:
		break;
	case OdDb::kOsModePar:
		break;
	case OdDb::kOsModeStart:
		pArc->getStartPoint(ptOsnap);
		snapPoints.append(ptOsnap);
		break;
	default:
		break;
	}

	return eOk;//OdDbGripPointsPE::getOsnapPoints(pEntity, osnapMode, gsSelectionMark, pickPoint, lastPoint, xWorldToEye, snapPoints);
}

塊:get

OdResult CMdEdBlockGripPointsEx::getGripPoints(
    const OdDbEntity* pEntity,
    OdDbGripDataPtrArray& grips,
    const double curViewUnitSize,
    const int gripSize,
    const OdGeVector3d& curViewDir,
    const int bitFlags ) const
{
    OdDbBlockReference* pBlock = OdDbBlockReference::cast(pEntity);
    if(pBlock == NULL)
    {
        return eOk;
    }

	OdGePoint3d ptPoint = pBlock->position();
	OdDbGripData* pGripData = NULL;
	pGripData = new OdDbGripData;
	pGripData->setGizmosEnabled(true);
	pGripData->setAppData((void*)kInsertPoint);
	pGripData->setGripPoint(ptPoint);
	grips.append(pGripData);

    return eOk;
}

OdResult CMdEdBlockGripPointsEx::moveGripPointsAt(
    OdDbEntity* pEntity,
    const OdDbVoidPtrArray& grips,
    const OdGeVector3d& offset,
    int bitFlags )
{
    OdDbBlockReferencePtr pBlock = OdDbBlockReference::cast(pEntity);

    for (int i=0;i<(int)grips.size();i++)
    {
        OdDbGripData* pGripData = (OdDbGripData*)grips.at(i);

        switch ((int)pGripData->appData())
        {
        case kInsertPoint:
            {
                OdGeMatrix3d mat;
                mat.setTranslation(offset);
                pBlock->transformBy(mat);
            }
            break;
        default:
            break;
        }
    }

    return eOk;
}

OdResult CMdEdBlockGripPointsEx::getOsnapPoints( 
    const OdDbEntity* pEntity, 
    OdDb::OsnapMode osnapMode, 
    OdGsMarker gsSelectionMark, 
    const OdGePoint3d& pickPoint,
    const OdGePoint3d& lastPoint, 
    const OdGeMatrix3d& xWorldToEye, 
    OdGePoint3dArray& snapPoints ) const
{
	OdDbBlockReference* pBlock = OdDbBlockReference::cast(pEntity);
	if(pBlock == NULL || gsSelectionMark < 1)
	{
		return eOk;
	}

	int nStartIndex = (int)gsSelectionMark - 1;

	OdGePoint3d ptOsnap; 
	if (osnapMode == OdDb::kOsModeIns)
	{
		ptOsnap = pBlock->position();
		snapPoints.append(ptOsnap);
	}
	else
	{
		OdRxObjectPtrArray entitySet;
		pBlock->explode(entitySet);
		OdDbEntity* pEnt = OdDbEntity::cast(entitySet.at(nStartIndex));
		pEnt->getOsnapPoints(osnapMode,gsSelectionMark,pickPoint,lastPoint,xWorldToEye,snapPoints);
	}

    return eOk;//OdDbGripPointsPE::getOsnapPoints(pEntity, osnapMode, gsSelectionMark, pickPoint, lastPoint, xWorldToEye, snapPoints);
}

圓:it

OdResult CMdEdCircleGripPointsEx::getGripPoints(
    const OdDbEntity* pEntity,
    OdDbGripDataPtrArray& grips,
    const double curViewUnitSize,
    const int gripSize,
    const OdGeVector3d& curViewDir,
    const int bitFlags ) const
{
    OdDbCircle* pCircle = OdDbCircle::cast(pEntity);
    if(pCircle == NULL)
    {
        return eOk;
    }

    OdGePoint3d centerPoint = pCircle->center();

	double dRadius = pCircle->radius();

	OdGeVector3d vect1 = dRadius * OdGeVector3d::kXAxis;
	OdGeVector3d vect2 = dRadius * OdGeVector3d::kYAxis;

	OdGePoint3d point1 = centerPoint + vect1;
	OdGePoint3d point2 = centerPoint - vect1;
	OdGePoint3d point3 = centerPoint + vect2;
	OdGePoint3d point4 = centerPoint - vect2;

    OdDbGripData* pGripData = NULL;

	pGripData = new OdDbGripData;
	pGripData->setAppData((void*)kCenterPoint);
	pGripData->setGripPoint(centerPoint);
	grips.append(pGripData);

    pGripData = new OdDbGripData;
    pGripData->setGizmosEnabled(true);
    pGripData->setAppData((void*)kQuadPoint);
    pGripData->setGripPoint(point1);
    grips.append(pGripData);

    pGripData = new OdDbGripData;
    pGripData->setGizmosEnabled(true);
    pGripData->setAppData((void*)kQuadPoint);
    pGripData->setGripPoint(point2);
    grips.append(pGripData);

    pGripData = new OdDbGripData;
    pGripData->setGizmosEnabled(true);
    pGripData->setAppData((void*)kQuadPoint);
    pGripData->setGripPoint(point3);
    grips.append(pGripData);

    pGripData = new OdDbGripData;
    pGripData->setGizmosEnabled(true);
    pGripData->setAppData((void*)kQuadPoint);
    pGripData->setGripPoint(point4);
    grips.append(pGripData);

    return eOk;
}

OdResult CMdEdCircleGripPointsEx::moveGripPointsAt(
    OdDbEntity* pEntity,
    const OdDbVoidPtrArray& grips,
    const OdGeVector3d& offset,
    int bitFlags )
{
    OdDbCirclePtr pCircle = OdDbCircle::cast(pEntity);

    for (int i=0;i<(int)grips.size();i++)
    {
        OdDbGripData* pGripData = (OdDbGripData*)grips.at(i);

        switch ((int)pGripData->appData())
        {
        case kCenterPoint:
            {
                OdGeMatrix3d mat;
                mat.setTranslation(offset);
                pCircle->transformBy(mat);
            }
            break;
        case kQuadPoint:
            {
                OdGePoint3d ptcenter = pCircle->center();
                OdGePoint3d ptQuadBef = pGripData->gripPoint();
                OdGePoint3d ptQuadAft = ptQuadBef + offset;
                double dRadius = ptcenter.distanceTo(ptQuadAft);
                pCircle->setRadius(dRadius);
            }
            break;
        default:
            break;
        }
    }

    return eOk;
}

OdResult CMdEdCircleGripPointsEx::getOsnapPoints( 
    const OdDbEntity* pEntity, 
    OdDb::OsnapMode osnapMode, 
    OdGsMarker gsSelectionMark, 
    const OdGePoint3d& pickPoint,
    const OdGePoint3d& lastPoint, 
    const OdGeMatrix3d& xWorldToEye, 
    OdGePoint3dArray& snapPoints ) const
{
	OdDbCircle* pCircle = OdDbCircle::cast(pEntity);
	if(pCircle == NULL)
	{
		return eOk;
	}

	OdGePoint3d ptOsnap; 
	switch(osnapMode)
	{
	case OdDb::kOsModeCen:
		ptOsnap = pCircle->center();
		snapPoints.append(ptOsnap);
		break;
	case OdDb::kOsModeNode:
		break;
	case OdDb::kOsModeQuad:
		{
			OdGePoint3d centerPoint = pCircle->center();
			double dRadius = pCircle->radius();
			OdGeVector3d vect1 = dRadius * OdGeVector3d::kXAxis;
			OdGeVector3d vect2 = dRadius * OdGeVector3d::kYAxis;

			OdGePoint3d ptOsnap = centerPoint + vect1;
			OdGePoint3d ptTemp = centerPoint - vect1;
			if (pickPoint.distanceTo(ptOsnap) > pickPoint.distanceTo(ptTemp))
				ptOsnap = ptTemp;

			ptTemp = centerPoint + vect2;
			if (pickPoint.distanceTo(ptOsnap) > pickPoint.distanceTo(ptTemp))
				ptOsnap = ptTemp;

			ptTemp = centerPoint - vect2;
			if (pickPoint.distanceTo(ptOsnap) > pickPoint.distanceTo(ptTemp))
				ptOsnap = ptTemp;

			snapPoints.append(ptOsnap);
			break;
		}
	case OdDb::kOsModeIntersec:
		break;
	case OdDb::kOsModePerp:
		{
			OdGePoint3d ptCircle = pCircle->center();
			OdGeLine3d line3d(ptCircle,lastPoint);   
			OdGeCircArc3d circle(ptCircle,pCircle->normal(),pCircle->radius());
			OdGePoint3d ptOsnap,ptTemp;
			int nNum = 0;
			if (circle.intersectWith(line3d,nNum,ptOsnap,ptTemp))
			{
				if (pickPoint.distanceTo(ptOsnap) > pickPoint.distanceTo(ptTemp))
					ptOsnap = ptTemp;
			}
			snapPoints.append(ptOsnap);
		}
		break;
	case OdDb::kOsModeTan:
		{
			OdGePoint3d ptCenter = pCircle->center();
			double dRadius = pCircle->radius();
			double dLastToCenter = lastPoint.distanceTo(ptCenter);//圓外一點到圓心距離
            if (OdZero(dLastToCenter))
            {
                return eOk;
            }
            double dcos = dRadius/dLastToCenter;
            if (dcos > 1.0)
            {
                return eOk;
            }
            double dAngle = acos(dcos);

			//旋轉圓外一點到圓心的直線
			OdGeVector3d vecCenterToLast =  (lastPoint - ptCenter).normalize()*dRadius;
			OdGeVector3d vecRadius1 = vecCenterToLast;
            vecRadius1.rotateBy(dAngle,pCircle->normal());			
			OdGePoint3d ptTemp1 = ptCenter + vecRadius1;

            OdGeVector3d vecRadius2 = vecCenterToLast;
            vecRadius2.rotateBy(-dAngle,pCircle->normal());
			OdGePoint3d ptTemp2 = ptCenter + vecRadius2;

			if (pickPoint.distanceTo(ptTemp1) < pickPoint.distanceTo(ptTemp2))
            {
                ptOsnap = ptTemp1;
            }
            else
            {
                ptOsnap = ptTemp2;
            }

			snapPoints.append(ptOsnap);
			break;
		}
	case OdDb::kOsModeNear:
		{
/*
			OdGeCircArc3d circle(pCircle->center(),pCircle->normal(),pCircle->radius());
			OdGePointOnCurve3d tmpPt;
			circle.getClosestPointTo(pickPoint,tmpPt);
			ptOsnap=tmpPt.point();
			snapPoints.append(ptOsnap);
*/
			break;
		}
	case OdDb::kOsModeApint:
		break;
	case OdDb::kOsModePar:
		break;
	default:
		break;
	}

    return eOk;//OdDbGripPointsPE::getOsnapPoints(pEntity, osnapMode, gsSelectionMark, pickPoint, lastPoint, xWorldToEye, snapPoints);
}

橢圓:io

OdResult CMdEdEllipseGripPointsEx::getGripPoints(
    const OdDbEntity* pEntity,
    OdDbGripDataPtrArray& grips,
    const double curViewUnitSize,
    const int gripSize,
    const OdGeVector3d& curViewDir,
    const int bitFlags ) const
{
    OdDbEllipse* pEllipse = OdDbEllipse::cast(pEntity);
    if(pEllipse == NULL)
    {
        return eOk;
    }

    OdGePoint3d centerPoint = pEllipse->center();

	OdGeVector3d vecMajor = pEllipse->majorAxis();
	OdGeVector3d vecMinor = pEllipse->minorAxis();

	OdGePoint3d point1 = centerPoint - vecMajor;
	OdGePoint3d point2 = centerPoint + vecMajor;
	OdGePoint3d point3 = centerPoint - vecMinor;
	OdGePoint3d point4 = centerPoint + vecMinor;

    OdDbGripData* pGripData = NULL;

	pGripData = new OdDbGripData;
	pGripData->setAppData((void*)kCenterPoint);
	pGripData->setGripPoint(centerPoint);
	grips.append(pGripData);

    pGripData = new OdDbGripData;
    pGripData->setGizmosEnabled(true);
    pGripData->setAppData((void*)kMajorPoint);
    pGripData->setGripPoint(point1);
    grips.append(pGripData);

    pGripData = new OdDbGripData;
    pGripData->setGizmosEnabled(true);
    pGripData->setAppData((void*)kMajorPoint);
    pGripData->setGripPoint(point2);
    grips.append(pGripData);

    pGripData = new OdDbGripData;
    pGripData->setGizmosEnabled(true);
    pGripData->setAppData((void*)kMinorPoint);
    pGripData->setGripPoint(point3);
    grips.append(pGripData);

    pGripData = new OdDbGripData;
    pGripData->setGizmosEnabled(true);
    pGripData->setAppData((void*)kMinorPoint);
    pGripData->setGripPoint(point4);
    grips.append(pGripData);

    return eOk;
}


OdResult CMdEdEllipseGripPointsEx::moveGripPointsAt(
    OdDbEntity* pEntity,
    const OdDbVoidPtrArray& grips,
    const OdGeVector3d& offset,
    int bitFlags )
{
    OdDbEllipsePtr pEllipse = OdDbEllipse::cast(pEntity);

    for (int i=0;i<(int)grips.size();i++)
    {
        OdDbGripData* pGripData = (OdDbGripData*)grips.at(i);

        switch ((int)pGripData->appData())
        {
        case kCenterPoint:
            {
                OdGeMatrix3d mat;
                mat.setTranslation(offset);
                pEllipse->transformBy(mat);
            }
            break;
        case kMajorPoint:
            {
                OdGePoint3d ptcenter = pEllipse->center();
                OdGePoint3d ptQuadBef = pGripData->gripPoint();
                OdGePoint3d ptQuadAft = ptQuadBef + offset;
                double dMajorRadius = ptcenter.distanceTo(ptQuadAft);
                OdGeVector3d vecMinorRadius = pEllipse->minorAxis();
                if (dMajorRadius > 1e-6 && vecMinorRadius.length() / dMajorRadius < 1)
                {  
                     pEllipse->setRadiusRatio(vecMinorRadius.length() / dMajorRadius);    
                }
            }
            break;
        case kMinorPoint:
            {
                OdGePoint3d ptcenter = pEllipse->center();
                OdGePoint3d ptQuadBef = pGripData->gripPoint();
                OdGePoint3d ptQuadAft = ptQuadBef + offset;
                double dMinorRadius = ptcenter.distanceTo(ptQuadAft);
                OdGeVector3d vecMajorRadius = pEllipse->majorAxis();
                if (dMinorRadius > 1e-6 && dMinorRadius / vecMajorRadius.length() < 1)
                {
                    pEllipse->setRadiusRatio(dMinorRadius / vecMajorRadius.length());
                }
            }
            break;
        default:
            break;
        }
    }

    return eOk;
}

OdResult CMdEdEllipseGripPointsEx::getOsnapPoints( 
    const OdDbEntity* pEntity, 
    OdDb::OsnapMode osnapMode, 
    OdGsMarker gsSelectionMark, 
    const OdGePoint3d& pickPoint,
    const OdGePoint3d& lastPoint, 
    const OdGeMatrix3d& xWorldToEye, 
    OdGePoint3dArray& snapPoints ) const
{
	OdDbEllipse* pEllipse = OdDbEllipse::cast(pEntity);
	if(pEllipse == NULL)
	{
		return eOk;
	}

	OdGePoint3d ptOsnap; 

   switch(osnapMode)
   {
   case OdDb::kOsModeCen:
	   ptOsnap = pEllipse->center();
	   snapPoints.append(ptOsnap);
	   break;
   case OdDb::kOsModeNode:
	   break;
   case OdDb::kOsModeQuad:
	   {
		   OdGePoint3d centerPoint = pEllipse->center();

		   OdGeVector3d vecMajor = pEllipse->majorAxis();
		   OdGeVector3d vecMinor = pEllipse->minorAxis();

		   OdGePoint3d ptOsnap = centerPoint - vecMajor;
		   OdGePoint3d ptTemp = centerPoint + vecMajor;
		   if (pickPoint.distanceTo(ptOsnap) > pickPoint.distanceTo(ptTemp))
				ptOsnap = ptTemp;
				
		   ptTemp = centerPoint - vecMinor;
		   if (pickPoint.distanceTo(ptOsnap) > pickPoint.distanceTo(ptTemp))
				ptOsnap = ptTemp;
				
		   ptTemp = centerPoint + vecMinor;
		   if (pickPoint.distanceTo(ptOsnap) > pickPoint.distanceTo(ptTemp))
				ptOsnap = ptTemp;
			
		   snapPoints.append(ptOsnap);	
		   break;
	   }
	   
   case OdDb::kOsModeIntersec:
	   break;
   case OdDb::kOsModePerp:
	   break;
   case OdDb::kOsModeTan:
	   break;
   case OdDb::kOsModeNear:
	   {
           /*
		   OdGeEllipArc3d ellipse(pEllipse->center(),pEllipse->majorAxis(),pEllipse->minorAxis(),pEllipse->majorAxis().length(),pEllipse->minorAxis().length());
		   OdGePointOnCurve3d tmpPt;
		   ellipse.getClosestPointTo(pickPoint,tmpPt);
		   ptOsnap=tmpPt.point();
		   snapPoints.append(ptOsnap);
           */
		   break;
	   }
   case OdDb::kOsModeApint:
	   break;
   case OdDb::kOsModePar:
	   break;
   default:
	   break;
   }
	return eOk;//OdDbGripPointsPE::getOsnapPoints(pEntity, osnapMode, gsSelectionMark, pickPoint, lastPoint, xWorldToEye, snapPoints);
}

直線:

OdResult CMdEdLineGripPointsEx::getGripPoints(
    const OdDbEntity* pEntity,
    OdDbGripDataPtrArray& grips,
    const double curViewUnitSize,
    const int gripSize,
    const OdGeVector3d& curViewDir,
    const int bitFlags ) const
{
    OdDbLine* pLine = OdDbLine::cast(pEntity);
    if(pLine == NULL)
    {
        return eOk;
    }

    OdGePoint3d startPoint;
    OdGePoint3d midPoint;
    OdGePoint3d endPoint;

    pLine->getStartPoint(startPoint);
    pLine->getEndPoint(endPoint);
    midPoint = (startPoint + endPoint.asVector())/2.0;

    OdDbGripData* pGripData = NULL;

    pGripData = new OdDbGripData;
    pGripData->setGizmosEnabled(true);
    pGripData->setAppData((void*)kStartPoint);
    pGripData->setGripPoint(startPoint);
    grips.append(pGripData);

    pGripData = new OdDbGripData;
    pGripData->setAppData((void*)kMidPoint);
    pGripData->setGripPoint(midPoint);
    grips.append(pGripData);

    pGripData = new OdDbGripData;
    pGripData->setGizmosEnabled(true);
    pGripData->setAppData((void*)kEndPoint);
    pGripData->setGripPoint(endPoint);
    grips.append(pGripData);

    return eOk;
}

OdResult CMdEdLineGripPointsEx::moveGripPointsAt(
    OdDbEntity* pEntity,
    const OdDbVoidPtrArray& grips,
    const OdGeVector3d& offset,
    int bitFlags )
{
    OdDbLinePtr pLine = OdDbLine::cast(pEntity);

    for (int i=0;i<(int)grips.size();i++)
    {
        OdDbGripData* pGripData = (OdDbGripData*)grips.at(i);

        switch ((int)pGripData->appData())
        {
        case kStartPoint:
            {
                OdGePoint3d ptStart = pLine->startPoint();
                ptStart += offset;
                pLine->setStartPoint(ptStart);
            }
            break;
        case kMidPoint:
            {
                OdGeMatrix3d mat;
                mat.setTranslation(offset);
                pLine->transformBy(mat);
            }
            break;
        case kEndPoint:
            {
                OdGePoint3d ptEnd = pLine->endPoint();
                ptEnd += offset;
                pLine->setEndPoint(ptEnd);
            }
            break;
        default:
            break;
        }
    }

    return eOk;
}

OdResult CMdEdLineGripPointsEx::getOsnapPoints( 
    const OdDbEntity* pEntity, 
    OdDb::OsnapMode osnapMode, 
    OdGsMarker gsSelectionMark, 
    const OdGePoint3d& pickPoint,
    const OdGePoint3d& lastPoint, 
    const OdGeMatrix3d& xWorldToEye, 
    OdGePoint3dArray& snapPoints ) const
{
	OdDbLine* pLine = OdDbLine::cast(pEntity);
	if(pLine == NULL)
	{
		return eOk;
	}

	//acedTrans
// 	OdGePlane *gePlane = new OdGePlane();
// 	xWorldToEye.setToWorldToPlane(*gePlane);

	OdGePoint3d ptOsnap;
	switch (osnapMode)
	{
	case OdDb::kOsModeEnd:
		{
			OdGePoint3d tempPoint;
			pLine->getStartPoint(ptOsnap);
			pLine->getEndPoint(tempPoint);
			if (pickPoint.distanceTo(ptOsnap) > pickPoint.distanceTo(tempPoint))
				ptOsnap = tempPoint;

			snapPoints.append(ptOsnap);
			break;
		}
	case OdDb::kOsModeMid:
		{
			OdGePoint3d startPoint,endPoint;
			pLine->getStartPoint(startPoint);
			pLine->getEndPoint(endPoint);
			ptOsnap = (startPoint + endPoint.asVector())/2.0;
			//ptTemp = xWorldToEye * *ptTemp;
			snapPoints.append(ptOsnap);
			break;
		}
	case OdDb::kOsModeNode:
		break;
	case OdDb::kOsModeQuad:
		break;
	case OdDb::kOsModeIntersec:
		break;
	case OdDb::kOsModePerp:
		{
			OdGePoint3d startPoint,endPoint;
			pLine->getStartPoint(startPoint);
			pLine->getEndPoint(endPoint);
			OdGeLine3d line3d(startPoint,endPoint);         
			OdGePointOnCurve3d tmpPt;
			line3d.getClosestPointTo(lastPoint,tmpPt);
			ptOsnap=tmpPt.point();
			snapPoints.append(ptOsnap);
			break;
		}
	case OdDb::kOsModeNear:
		{
			OdGePoint3d startPoint,endPoint;
			pLine->getStartPoint(startPoint);
			pLine->getEndPoint(endPoint);
			OdGeLine3d line3d(startPoint,endPoint);         
			OdGePointOnCurve3d tmpPt;
			line3d.getClosestPointTo(pickPoint,tmpPt);
			ptOsnap=tmpPt.point();
			snapPoints.append(ptOsnap);
			break;
		}
	case OdDb::kOsModeApint:
		break;
	case OdDb::kOsModePar:
		break;
	case OdDb::kOsModeStart:
		pLine->getStartPoint(ptOsnap);
		snapPoints.append(ptOsnap);
		break;
	default:
		break;
	}
    return eOk;//OdDbGripPointsPE::getOsnapPoints(pEntity, osnapMode, gsSelectionMark, pickPoint, lastPoint, xWorldToEye, snapPoints);
}

多行文本:

OdResult CMdEdMTextGripPointsEx::getGripPoints(
    const OdDbEntity* pEntity,
    OdDbGripDataPtrArray& grips,
    const double curViewUnitSize,
    const int gripSize,
    const OdGeVector3d& curViewDir,
    const int bitFlags ) const
{
    OdDbMText* pMText = OdDbMText::cast(pEntity);
    if(pMText == NULL)
    {
        return eOk;
    }

	    OdGePoint3d ptPos = pMText->location();
    OdDbGripData* pGripData = NULL;
    pGripData = new OdDbGripData;
    pGripData->setGizmosEnabled(true);
    pGripData->setAppData((void*)kPosPoint);
    pGripData->setGripPoint(ptPos);
    grips.append(pGripData);

    double dWidth = pMText->width();
    double dHeight = pMText->actualHeight();//height();
    double dAngle = pMText->rotation();
    
    OdDb::TextVertMode vertMode = pMText->verticalMode();
    OdDb::TextHorzMode horzMode = pMText->horizontalMode();
    double dxOffset = 0.0,dyOffset = 0.0 ;
    if (vertMode == OdDb::kTextTop)
        dyOffset = - dHeight ;
    else if (vertMode == OdDb::kTextVertMid)
        dyOffset = - dHeight / 2;
    else if (vertMode == OdDb::kTextBottom)
        dyOffset = dHeight ;

    if (horzMode == OdDb::kTextLeft)
        dxOffset = dWidth ;
    else if (horzMode == OdDb::kTextCenter)
        dxOffset =  dWidth / 2;
    else if (horzMode == OdDb::kTextRight)
        dxOffset = - dWidth ;

    OdGePoint3d ptWidth = ptPos + dxOffset * OdGeVector3d::kXAxis;
    OdGePoint3d ptHeight = ptPos + dyOffset * OdGeVector3d::kYAxis + dxOffset * OdGeVector3d::kXAxis / 2;
    if (horzMode == OdDb::kTextCenter)
        ptHeight = ptPos + dyOffset * OdGeVector3d::kYAxis;
    
    if (dAngle != 0)
    {
        //寬
        OdDbLine line;
        line.setStartPoint(ptPos);
        line.setEndPoint(ptWidth); 
        OdGeMatrix3d xform;
        OdGeVector3d vec(0, 0, 1);
        xform.setToRotation(dAngle, vec,ptPos);
        line.transformBy(xform);
        ptWidth = line.endPoint();

        //高
        line.setEndPoint(ptHeight);
        xform.setToRotation(MdPI4 - dAngle, vec, ptPos);
        line.transformBy(xform);
        ptHeight = line.endPoint();
    }

    pGripData = new OdDbGripData;
    pGripData->setGizmosEnabled(true);
    pGripData->setAppData((void*)kWidthPoint);
    pGripData->setGripPoint(ptWidth);
    grips.append(pGripData);

    pGripData = new OdDbGripData;
    pGripData->setGizmosEnabled(true);
    pGripData->setAppData((void*)kHeightPoint);
    pGripData->setGripPoint(ptHeight);
    grips.append(pGripData);
	
    return eOk;
}

OdResult CMdEdMTextGripPointsEx::moveGripPointsAt(
    OdDbEntity* pEntity,
    const OdDbVoidPtrArray& grips,
    const OdGeVector3d& offset,
    int bitFlags )
{
    OdDbMTextPtr pMText = OdDbMText::cast(pEntity);

    for (int i=0;i<(int)grips.size();i++)
    {
        OdDbGripData* pGripData = (OdDbGripData*)grips.at(i);

        switch ((int)pGripData->appData())
        {
        case kPosPoint:
            {
                OdGeMatrix3d mat;
                mat.setTranslation(offset);
                pMText->transformBy(mat);
            }
            break;
        case kWidthPoint:
            {
                OdGeMatrix3d mat;
                mat.setTranslation(offset);
                pMText->transformBy(mat);
            }
            break;
        case kHeightPoint:
            {
                OdGeMatrix3d mat;
                mat.setTranslation(offset);
                pMText->transformBy(mat);
            }
            break;
        default:
            break;
        }
    }

    return eOk;
}

OdResult CMdEdMTextGripPointsEx::getOsnapPoints( 
    const OdDbEntity* pEntity, 
    OdDb::OsnapMode osnapMode, 
    OdGsMarker gsSelectionMark, 
    const OdGePoint3d& pickPoint,
    const OdGePoint3d& lastPoint, 
    const OdGeMatrix3d& xWorldToEye, 
    OdGePoint3dArray& snapPoints ) const
{
	OdDbMText* pMText = OdDbMText::cast(pEntity);
	if(pMText == NULL)
	{
		return eOk;
	}

	OdGePoint3d ptOsnap; 
	switch(osnapMode)
	{
	case OdDb::kOsModeNode:
		break;
	case OdDb::kOsModeQuad:
		break;
	case OdDb::kOsModeIntersec:
		break;
	case OdDb::kOsModeIns:
		ptOsnap = pMText->location();
		snapPoints.append(ptOsnap);
		break;
	case OdDb::kOsModePerp:
		break;
	case OdDb::kOsModeTan:
		break;
	case OdDb::kOsModeNear:
		break;
	default:
		break;
	}

    return eOk;//OdDbGripPointsPE::getOsnapPoints(pEntity, osnapMode, gsSelectionMark, pickPoint, lastPoint, xWorldToEye, snapPoints);
}

多段線:

OdResult CMdEdPolyLineGripPointsEx::getGripPoints(
    const OdDbEntity* pEntity,
    OdDbGripDataPtrArray& grips,
    const double curViewUnitSize,
    const int gripSize,
    const OdGeVector3d& curViewDir,
    const int bitFlags ) const
{
    OdDbPolyline* pPolyLine = OdDbPolyline::cast(pEntity);
    if(pPolyLine == NULL)
    {
        return eOk;
    }

    OdGePoint3d startPoint;
    OdGePoint3d endPoint;

    pPolyLine->getStartPoint(startPoint);
    pPolyLine->getEndPoint(endPoint);

	OdDbGripData* pGripData = NULL;

	pGripData = new OdDbGripData;
	pGripData->setGizmosEnabled(true);
	pGripData->setAppData((void*)kStartPoint);
	pGripData->setGripPoint(startPoint);
	grips.append(pGripData);

	pGripData = new OdDbGripData;
	pGripData->setGizmosEnabled(true);
	pGripData->setAppData((void*)kEndPoint);
	pGripData->setGripPoint(endPoint);
	grips.append(pGripData);

	OdGePoint3d tempPoint;
	int nNum = pPolyLine->numVerts();
	for (int i = 1; i < nNum -1; ++i)
	{
		pPolyLine->getPointAt(i,tempPoint);
		pGripData = new OdDbGripData;
		pGripData->setAppData((void*)kSegMidPoint);
		pGripData->setGripPoint(tempPoint);
		grips.append(pGripData);
	}

    //若是爲圓弧
    for (int i = 0; i < nNum; ++i)
    {
        if (pPolyLine->segType(i) == OdDbPolyline::kArc)
        {
            OdGeCircArc3d* pCircleArc = new OdGeCircArc3d;
            pPolyLine->getArcSegAt(i, *pCircleArc);
            OdGePoint3d ptMin;
            OdGePoint3d centerPoint = pCircleArc->center();
            OdGePoint3d startPoint =  pCircleArc->startPoint();
            OdGePoint3d endPoint = pCircleArc->endPoint();

            OdGeVector3d vecChord = startPoint - endPoint;
            OdGeVector3d vecNormal = pCircleArc->normal();
            OdGeVector3d vecCenter2Mid = vecNormal.crossProduct(vecChord);
            OdGeLine3d geLine(centerPoint, vecCenter2Mid);

            int nNum = 0;
            OdGePoint3d ptTemp;
            if(pCircleArc->intersectWith(geLine, nNum, ptMin, ptTemp))
            {
                if (pCircleArc->isOn(ptTemp))
                    ptMin = ptTemp;
            }

            pGripData = new OdDbGripData;
            pGripData->setAppData((void*)kArcMidPoint);
            pGripData->setGripPoint(ptMin);
            grips.append(pGripData);
        }
    }

    return eOk;
}

OdResult CMdEdPolyLineGripPointsEx::moveGripPointsAt(
    OdDbEntity* pEntity,
    const OdDbVoidPtrArray& grips,
    const OdGeVector3d& offset,
    int bitFlags )
{
    OdDbPolylinePtr pPolyLine = OdDbPolyline::cast(pEntity);

    for (int i=0;i<(int)grips.size();i++)
    {
        OdDbGripData* pGripData = (OdDbGripData*)grips.at(i);

        switch ((int)pGripData->appData())
        {
        case kStartPoint:
            {
                OdGePoint3d ptStart;
                pPolyLine->getStartPoint(ptStart);
                ptStart += offset;
                OdGePoint2d ptStart2d(ptStart.x,ptStart.y);
                pPolyLine->setPointAt(0,ptStart2d);
            }
            break;
        case kSegMidPoint:
            {
                OdGePoint3d ptBef = pGripData->gripPoint();
                OdGePoint3d ptAft = ptBef + offset;
                OdGePoint2d ptAft2d(ptAft.x,ptAft.y);
                for (int i = 1; i < pPolyLine->numVerts() - 1; i++)
                {
                    OdGePoint3d ptTemp;
                    pPolyLine->getPointAt(i,ptTemp);
                    if (ptBef == ptTemp)
                    {
                        pPolyLine->setPointAt(i,ptAft2d);
                        break;;
                    }
                } 
            }
            break;
        case kArcMidPoint:
            {
                OdGeMatrix3d mat;
                mat.setTranslation(offset);
                pPolyLine->transformBy(mat);
            }
            break;
        case kEndPoint:
            {
                OdGePoint3d ptEnd;
                pPolyLine->getEndPoint(ptEnd);
                ptEnd += offset;
                int nIndex = pPolyLine->numVerts();
                OdGePoint2d ptEnd2d(ptEnd.x, ptEnd.y);
                pPolyLine->setPointAt(nIndex - 1, ptEnd2d);
            }
            break;
        default:
            break;
        }
    }

    return eOk;
}

OdResult CMdEdPolyLineGripPointsEx::getOsnapPoints( 
    const OdDbEntity* pEntity, 
    OdDb::OsnapMode osnapMode, 
    OdGsMarker gsSelectionMark, 
    const OdGePoint3d& pickPoint,
    const OdGePoint3d& lastPoint, 
    const OdGeMatrix3d& xWorldToEye, 
    OdGePoint3dArray& snapPoints ) const
{
	OdDbPolyline* pPolyLine = OdDbPolyline::cast(pEntity);
	if(pPolyLine == NULL || gsSelectionMark < 1)
	{
		return eOk;
	}


	int nStartIndex = (int)gsSelectionMark - 1;

	OdGePoint3d ptOsnap; 
	switch(osnapMode)
	{
	case OdDb::kOsModeEnd:
		{
			OdGePoint3d tempPoint;
			pPolyLine->getPointAt(nStartIndex,ptOsnap);
			pPolyLine->getPointAt(nStartIndex + 1,tempPoint);

			if (pickPoint.distanceTo(ptOsnap) > pickPoint.distanceTo(tempPoint))
				ptOsnap = tempPoint;

			snapPoints.append(ptOsnap);
			break;
		}	
	case OdDb::kOsModeMid:
		{
			OdGePoint3d startPoint,endPoint;
			pPolyLine->getPointAt(nStartIndex,startPoint);
			pPolyLine->getPointAt(nStartIndex + 1,endPoint);
			ptOsnap = (startPoint + endPoint.asVector())/2.0;

			snapPoints.append(ptOsnap);
			break;
		}
	case OdDb::kOsModeNode:
		break;
	case OdDb::kOsModeQuad:
		break;
	case OdDb::kOsModeIntersec:
		break;
	case OdDb::kOsModePerp:
		{
			OdGePoint3d startPoint,endPoint;
			pPolyLine->getPointAt(nStartIndex,startPoint);
			pPolyLine->getPointAt(nStartIndex + 1,endPoint);
			OdGeLine3d line3d(startPoint,endPoint);         
			OdGePointOnCurve3d tmpPt;
			line3d.getClosestPointTo(lastPoint,tmpPt);
			ptOsnap=tmpPt.point();
				
			snapPoints.append(ptOsnap);
			break;
		}
	case OdDb::kOsModeTan:
		break;
	case OdDb::kOsModeNear:
		{
			OdGePoint3d startPoint,endPoint;
			pPolyLine->getPointAt(nStartIndex,startPoint);
			pPolyLine->getPointAt(nStartIndex + 1,endPoint);
			OdGeLine3d line3d(startPoint,endPoint);         
			OdGePointOnCurve3d tmpPt;
			line3d.getClosestPointTo(pickPoint,tmpPt);
			ptOsnap=tmpPt.point();
			snapPoints.append(ptOsnap);
			break;
		}
	case OdDb::kOsModeApint:
		break;
	case OdDb::kOsModePar:
		break;
	case OdDb::kOsModeStart:
		break;
	default:
		break;
	}
    return eOk;//OdDbGripPointsPE::getOsnapPoints(pEntity, osnapMode, gsSelectionMark, pickPoint, lastPoint, xWorldToEye, snapPoints);
}

文本:

OdResult CMdEdTextGripPointsEx::getGripPoints(
    const OdDbEntity* pEntity,
    OdDbGripDataPtrArray& grips,
    const double curViewUnitSize,
    const int gripSize,
    const OdGeVector3d& curViewDir,
    const int bitFlags ) const
{
    OdDbText* pText = OdDbText::cast(pEntity);
    if(pText == NULL)
    {
        return eOk;
    }

	OdGePoint3d ptPos= pText->position();
	OdDbGripData* pGripData = NULL;
	pGripData = new OdDbGripData;
	pGripData->setGizmosEnabled(true);
	pGripData->setAppData((void*)kPosPoint);
	pGripData->setGripPoint(ptPos);
	grips.append(pGripData);

    OdDb::TextVertMode modeVert = pText->verticalMode();
    OdDb::TextHorzMode modeHorz = pText->horizontalMode();
    if (!(modeHorz == OdDb::kTextLeft && modeVert == OdDb::kTextBase))
    {
        OdGePoint3d ptAlignment = pText->alignmentPoint();
        if (ptAlignment != OdGePoint3d(0,0,0) && ptAlignment != ptPos)
        {
            pGripData = new OdDbGripData;
            pGripData->setGizmosEnabled(true);
            pGripData->setAppData((void*)kAlignmentPoint);
            pGripData->setGripPoint(ptAlignment);
            grips.append(pGripData);
        }
    }

    return eOk;
}

OdResult CMdEdTextGripPointsEx::moveGripPointsAt(
    OdDbEntity* pEntity,
    const OdDbVoidPtrArray& grips,
    const OdGeVector3d& offset,
    int bitFlags )
{
    OdDbTextPtr pText = OdDbText::cast(pEntity);

    for (int i=0;i<(int)grips.size();i++)
    {
        OdDbGripData* pGripData = (OdDbGripData*)grips.at(i);

        switch ((int)pGripData->appData())
        {
        case kPosPoint:
            {
                OdGeMatrix3d mat;
                mat.setTranslation(offset);
                pText->transformBy(mat);
            }
            break;
        case kAlignmentPoint:
            {

                OdGeMatrix3d mat;
                mat.setTranslation(offset);
                pText->transformBy(mat);
            }
            break;
        default:
            break;
        }
    }

    return eOk;
}

OdResult CMdEdTextGripPointsEx::getOsnapPoints( 
    const OdDbEntity* pEntity, 
    OdDb::OsnapMode osnapMode, 
    OdGsMarker gsSelectionMark, 
    const OdGePoint3d& pickPoint,
    const OdGePoint3d& lastPoint, 
    const OdGeMatrix3d& xWorldToEye, 
    OdGePoint3dArray& snapPoints ) const
{
	OdDbText* pText = OdDbText::cast(pEntity);
	if(pText == NULL)
	{
		return eOk;
	}

	OdGePoint3d ptOsnap; 
	switch(osnapMode)
	{
	case OdDb::kOsModeNode:
		break;
	case OdDb::kOsModeQuad:
		break;
	case OdDb::kOsModeIntersec:
		break;
	case OdDb::kOsModeIns:
		ptOsnap = pText->position();
		snapPoints.append(ptOsnap);
		break;
	case OdDb::kOsModePerp:
		break;
	case OdDb::kOsModeTan:
		break;
	case OdDb::kOsModeNear:
		break;
	default:
		break;
	}

    return eOk;//OdDbGripPointsPE::getOsnapPoints(pEntity, osnapMode, gsSelectionMark, pickPoint, lastPoint, xWorldToEye, snapPoints);
}
相關文章
相關標籤/搜索