已知圓外一點,以及圓心半徑,求圓的切點: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); }