求一个圆弧算法问题,已知图形的两条边的终点起点,和圆弧半径,求圆心、圆弧起点、终点等

qq_39549728 2017-08-15 04:53:27
已知圆弧上切线 起点为 pt1,终点为pt2 . 切点为圆弧起始点,
下切线起点为 pt2,终点为pt2; 切点为圆弧终点。
圆弧半径为R;上切线和下切线夹角为 S; 圆心在其夹角角平分线上,
通过算法,算出圆心center, 起始点Stpoint,终点Edpoint 的坐标,
求大佬给出具体的实现过程

...全文
1274 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
jsxyhelu2015 2017-08-20
  • 打赏
  • 举报
回复
很专业的结果,点赞!
jsxyhelu2015 2017-08-20
  • 打赏
  • 举报
回复
引用 8 楼 schlafenhamster 的回复:
好一点了

#define PI 3.14159265359
#define Rd 40
BOOL CMyDlg::RoundChamfer(CPoint p1,CPoint p2,CPoint p3,CDC &dc)
{// angle a
	double dx21=p2.x-p1.x;// 180
	double dy21=p1.y-p2.y;// 180
	double a21;
	if(dx21==0)
	{
		a21=PI/2;// 90
	}
	else if(dx21 > 0)
	{
		a21=atan(dy21/dx21);
	}
	else
	{// <0
		a21=PI-atan(-dy21/dx21);
	}
	afxDump << a21*180/PI << " a度\n";
// angle b
	double dx23=p3.x-p2.x;// 120
	double dy23=p2.y-p3.y;// 280
	double b23;
	if(dx23==0)
	{
		b23=PI/2;// 90
	}
	else if(dx23 >0)
	{
		b23=PI-atan(-dy23/dx23);// 90
	}
	else
	{// <0
		b23=atan(dy23/dx23);
	}
//
	double s;
	s=(b23-a21)/2;
	afxDump << b23*180/PI << " b度\n";
// tangent line of circle
	double L=Rd/tan(s);
//
	double dBx=L*cos(a21);
	double dBy=L*sin(a21);
//
	CPoint B;// begin
	B.x=(int)(p2.x-dBx);
	B.y=(int)(p2.y+dBy);
//
	double dEx=L*cos(b23);
	double dEy=L*sin(b23);
	CPoint E;// end
	E.x=(int)(p2.x-dEx);
	E.y=(int)(p2.y+dEy);
//
	afxDump << (a21+s)*180/PI << " Mid度\n";
	double M=L/cos(s);// middle line
	double dCx=M*cos(a21+s);
	double dCy=M*sin(a21+s);
	CPoint C;// center
	C.x=(int)(p2.x-dCx);
	C.y=(int)(p2.y+dCy);
//
	dc.MoveTo(p1);
	dc.LineTo(p2);
	dc.LineTo(p3);
//
	dc.MoveTo(B);
	dc.LineTo(C);
	dc.LineTo(E);
//
	dc.MoveTo(C);
	dc.LineTo(p2);
//
	dc.SelectObject(GetStockObject(NULL_BRUSH));
	CRect rc(C.x-Rd,C.y-Rd,C.x+Rd,C.y+Rd);
	CPen pen;
	CPen *old;
	pen.CreatePen(PS_SOLID,2,RGB(255,0,0));
	old=dc.SelectObject(&pen);
	dc.MoveTo(p1);
	dc.LineTo(B);
	dc.Arc(rc, E,B);
	dc.MoveTo(E);
	dc.LineTo(p3);
//
	dc.SelectObject(old);
	return TRUE;
}
引用 6 楼 schlafenhamster 的回复:
一个例子 (不通用)

#define PI 3.14159265359
#define Rd 70
BOOL CMyDlg::RoundChamfer(CPoint p1,CPoint p2,CPoint p3,CDC &dc)
{// angle a
	double dx21=p2.x-p1.x;// 180
	double dy21=p1.y-p2.y;// 180
	double k1=dy21/dx21;
	double a21=0;
	if(dx21!=0) a21=atan(k1);// 0.78
	afxDump << a21*180/PI << " a度\n";
// angle b
	double dx23=p3.x-p2.x;// 120
	double dy23=p2.y-p3.y;// 280
	double k2=dy23/dx23;
	double b23=0;
	if(dy23!=0) b23=atan(k2);
	afxDump << b23*180/PI << " b度\n";
// angle 
// 设直线l1、l2的斜率存在,分别为k1、k2,
// l1与l2的夹角为θ,则tanθ=∣(k2- k1)/(1+ k1k2)∣.
	double s;
	if(k2>k1)
		s =atan((k2-k1)/(1+k1*k2));
	else
		s =atan((k1-k2)/(1+k1*k2));
	afxDump << s*180/PI << " s度\n";
	s /= 2;
// middle line
	double L=Rd/tan(s);
//
	double dBx=L*cos(a21);
	double dBy=L*sin(a21);
//
	CPoint B;// begin
	B.x=(int)(p2.x-dBx);
	B.y=(int)(p2.y+dBy);
//
	double dEx=L*cos(b23);
	double dEy=L*sin(b23);
	CPoint E;// end
	E.x=(int)(p2.x-dEx);
	E.y=(int)(p2.y+dEy);
//
	afxDump << (a21+s)*180/PI << " Mid度\n";
	double M=L/cos(s);// middle
	double dCx=M*cos(a21+s);
	double dCy=M*sin(a21+s);
	CPoint C;// center
	C.x=(int)(p2.x-dCx);
	C.y=(int)(p2.y+dCy);
//
	dc.MoveTo(p1);
	dc.LineTo(p2);
	dc.LineTo(p3);
//
	dc.MoveTo(B);
	dc.LineTo(C);
	dc.LineTo(E);
//
	dc.SelectObject(GetStockObject(NULL_BRUSH));
	CRect rc(C.x-Rd,C.y-Rd,C.x+Rd,C.y+Rd);
	
	dc.Ellipse(rc);
//
	return TRUE;
}
很专业的结果,点赞!
schlafenhamster 2017-08-20
  • 打赏
  • 举报
回复
好一点了

#define PI 3.14159265359
#define Rd 40
BOOL CMyDlg::RoundChamfer(CPoint p1,CPoint p2,CPoint p3,CDC &dc)
{// angle a
double dx21=p2.x-p1.x;// 180
double dy21=p1.y-p2.y;// 180
double a21;
if(dx21==0)
{
a21=PI/2;// 90
}
else if(dx21 > 0)
{
a21=atan(dy21/dx21);
}
else
{// <0
a21=PI-atan(-dy21/dx21);
}
afxDump << a21*180/PI << " a度\n";
// angle b
double dx23=p3.x-p2.x;// 120
double dy23=p2.y-p3.y;// 280
double b23;
if(dx23==0)
{
b23=PI/2;// 90
}
else if(dx23 >0)
{
b23=PI-atan(-dy23/dx23);// 90
}
else
{// <0
b23=atan(dy23/dx23);
}
//
double s;
s=(b23-a21)/2;
afxDump << b23*180/PI << " b度\n";
// tangent line of circle
double L=Rd/tan(s);
//
double dBx=L*cos(a21);
double dBy=L*sin(a21);
//
CPoint B;// begin
B.x=(int)(p2.x-dBx);
B.y=(int)(p2.y+dBy);
//
double dEx=L*cos(b23);
double dEy=L*sin(b23);
CPoint E;// end
E.x=(int)(p2.x-dEx);
E.y=(int)(p2.y+dEy);
//
afxDump << (a21+s)*180/PI << " Mid度\n";
double M=L/cos(s);// middle line
double dCx=M*cos(a21+s);
double dCy=M*sin(a21+s);
CPoint C;// center
C.x=(int)(p2.x-dCx);
C.y=(int)(p2.y+dCy);
//
dc.MoveTo(p1);
dc.LineTo(p2);
dc.LineTo(p3);
//
dc.MoveTo(B);
dc.LineTo(C);
dc.LineTo(E);
//
dc.MoveTo(C);
dc.LineTo(p2);
//
dc.SelectObject(GetStockObject(NULL_BRUSH));
CRect rc(C.x-Rd,C.y-Rd,C.x+Rd,C.y+Rd);
CPen pen;
CPen *old;
pen.CreatePen(PS_SOLID,2,RGB(255,0,0));
old=dc.SelectObject(&pen);
dc.MoveTo(p1);
dc.LineTo(B);
dc.Arc(rc, E,B);
dc.MoveTo(E);
dc.LineTo(p3);
//
dc.SelectObject(old);
return TRUE;
}


schlafenhamster 2017-08-19
  • 打赏
  • 举报
回复
调用: else { // CDialog::OnPaint(); CPaintDC dc(this); // device context for painting CPoint p1(20,220); CPoint p2(200,20); CPoint p3(140,280); RoundChamfer(p1,p2,p3,dc); }
schlafenhamster 2017-08-19
  • 打赏
  • 举报
回复
一个例子 (不通用)

#define PI 3.14159265359
#define Rd 70
BOOL CMyDlg::RoundChamfer(CPoint p1,CPoint p2,CPoint p3,CDC &dc)
{// angle a
double dx21=p2.x-p1.x;// 180
double dy21=p1.y-p2.y;// 180
double k1=dy21/dx21;
double a21=0;
if(dx21!=0) a21=atan(k1);// 0.78
afxDump << a21*180/PI << " a度\n";
// angle b
double dx23=p3.x-p2.x;// 120
double dy23=p2.y-p3.y;// 280
double k2=dy23/dx23;
double b23=0;
if(dy23!=0) b23=atan(k2);
afxDump << b23*180/PI << " b度\n";
// angle
// 设直线l1、l2的斜率存在,分别为k1、k2,
// l1与l2的夹角为θ,则tanθ=∣(k2- k1)/(1+ k1k2)∣.
double s;
if(k2>k1)
s =atan((k2-k1)/(1+k1*k2));
else
s =atan((k1-k2)/(1+k1*k2));
afxDump << s*180/PI << " s度\n";
s /= 2;
// middle line
double L=Rd/tan(s);
//
double dBx=L*cos(a21);
double dBy=L*sin(a21);
//
CPoint B;// begin
B.x=(int)(p2.x-dBx);
B.y=(int)(p2.y+dBy);
//
double dEx=L*cos(b23);
double dEy=L*sin(b23);
CPoint E;// end
E.x=(int)(p2.x-dEx);
E.y=(int)(p2.y+dEy);
//
afxDump << (a21+s)*180/PI << " Mid度\n";
double M=L/cos(s);// middle
double dCx=M*cos(a21+s);
double dCy=M*sin(a21+s);
CPoint C;// center
C.x=(int)(p2.x-dCx);
C.y=(int)(p2.y+dCy);
//
dc.MoveTo(p1);
dc.LineTo(p2);
dc.LineTo(p3);
//
dc.MoveTo(B);
dc.LineTo(C);
dc.LineTo(E);
//
dc.SelectObject(GetStockObject(NULL_BRUSH));
CRect rc(C.x-Rd,C.y-Rd,C.x+Rd,C.y+Rd);

dc.Ellipse(rc);
//
return TRUE;
}

victor_woo 2017-08-17
  • 打赏
  • 举报
回复

BOOL createArc(const GCPosition4D &pInt,const GCVector4D &vedge1,const GCVector4D &vedge2
					,double R,GCArc3D& arc)
{
	double angle = vedge1^vedge2;

	if(fabs(angle-GCMathConst::PI)<GCMathConst::ZERO)
		return FALSE;

	if(angle<GCMathConst::ZERO)
		return FALSE;

	GCVector4D vedge11 = vedge1.toUnitVector();
	GCVector4D vedge21 = vedge2.toUnitVector();

	GCVector4D centerLineV = vedge11+vedge21;

	centerLineV.normalize();

	GCPosition4D p1 = pInt + vedge11*(R/tan(angle/2));

	GCPosition4D p2 = pInt + vedge21*(R/tan(angle/2));

	GCPosition4D pCenter = pInt + centerLineV* (R/sin(angle/2));

	arc.create(pCenter,p1,p2,TRUE);

	return TRUE;
}

BOOL createArc(const GCLine3D &line1,const GCLine3D &line2,double r,GCArc3D& arc)
{
    GCPosition4D pInt;

    BOOL isIntersected = intersected(line1,line2,pInt);

    if(!isIntersected )
        return FALSE;

    return createArc(pInt,line1.getDirection(),line2.getDirection(),r,arc);
}

BOOL intersected(const GCLine3D &line1,const GCLine3D &line2,GCPosition4D &p)
{
	double distance1 = line1.getBase()-line2;

	if(distance1<GCMathConst::ZERO)
	{
		p.clone(line1.getBase());
		return TRUE;
	}

	if((line2.getBase()-line1)<GCMathConst::ZERO)
	{
		p.clone(line2.getBase());
		return TRUE;
	}

	GCVector4D v3 = line1.getDirection()|line2.getDirection();

	GCPlane3D plane(line1.getBase(),v3);

	BOOL samePlane = (line2.getBase()-plane)<GCMathConst::ZERO;

	if(!samePlane)
		return FALSE;

	double angle = (line1.getDirection())^(line2.getDirection());

	double len = distance1/sin(angle);

	GCPosition4D s1 = line1.getBase() + line1.getDirection() * len;

	if((s1-line2)<GCMathConst::ZERO)
	{
		p.clone(s1);
		return TRUE;
	}

	s1 = line1.getBase() + line1.getDirection() * (-len);

	p.clone(s1);

	return TRUE;
}
qq_39549728 2017-08-16
  • 打赏
  • 举报
回复
引用 2 楼 zhao4zhong1 的回复:
http://blog.csdn.net/thelibra12/article/details/6086910
圆弧起始点、圆心、终点都是要用几何算法计算出来的。 因为很久没用数学几何了,所以我想求的是这个数学几何算法,
zgl7903 2017-08-16
  • 打赏
  • 举报
回复
这个纯粹的初中几何问题,
shiter 2017-08-16
  • 打赏
  • 举报
回复
你是要代码呢,还是要咋算呢?

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧