有懂lisp编程的吗?一个用C写的求圆心程序帮忙改写成用lisp
在写AtuoCAD插件已知圆弧起点,终点,和凸度,求圆心的程序。原来用C写的,现在想改成lisp写。/********************************************************************
file base:main
file ext: cpp
author: scenic
purpose: 由起点和终点以及凸度求圆弧的圆心
*********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.141593
#define RESOLUTION 0.000001
typedef struct point
{
double x;
double y;
double z;
}Point,*PPoint;
typedef struct arc
{
double sx;
double sy;
double sz;
double ex;
double ey;
double ez;
double r;
double cx;
double cy;
double cz;
double startangle;
double endangle;
}ARC,*PARC;
int getArcR(Point startpoint ,Point endpoint ,double bulge,PARC parc);//圆弧起始点和终止点 和凸度
int getArcR(Point startpoint ,Point endpoint ,double bulge,PARC parc)
{
double x1(0.0),y1(0.0),x2(0.0),y2(0.0),arcangle(0.0);//圆弧起始点和终止点, 以及所包的角度
x1=startpoint.x;
y1=startpoint.y;
x2=endpoint.x;
y2=endpoint.y;
parc->sx=startpoint.x;
parc->sy=startpoint.y;
parc->sz=0.0;
parc->ex=endpoint.x;
parc->ey=endpoint.y;
parc->ez=0.0;
arcangle=4*atan(fabs(bulge)); //弧包含的弧度
printf("arcangle= %f \n",arcangle*180/PI);
if((-RESOLUTION<arcangle)&&(arcangle<RESOLUTION))
{
printf("LINE (x1= %f,y1=%f) (x2=%f,y2=%f) \n",x1,y1,x2,y2);
return 1;
}
double chordlength; //弦长
chordlength=sqrt(pow((x1-x2),2)+pow((y1-y2),2));
doubleradius; //圆弧半径
radius=(0.5*chordlength)/(sin(0.5*arcangle));
printf("r= %f\n",radius);
if((-RESOLUTION<(radius))&&((radius)<RESOLUTION))
{
printf("startpoint can't be same as endpoint \n");
return 1;
}
//--------------已知圆上两点和半径,求圆心坐标--------------------
double verticalinterval;//圆心到弦垂距
verticalinterval=sqrt( radius* radius-chordlength*chordlength/4);
double cx,cy;//圆心坐标
double midx,midy; //起始点和终止点连线的中点横纵坐标
midx=0.5*(x1+x2);
midy=0.5*(y1+y2);
if((-RESOLUTION<(bulge-1))&&((bulge-1)<RESOLUTION))
{
printf("arc: (x=%f y=%f r=%f ) \n",midx,midy, radius);
parc->cx=midx;
parc->cy=midy;
parc->cz=0.0;
parc->r=radius;
printf("x=%lf,y=%lf,z=%lf r=%f\n",parc->cx,parc->cy,parc->cz,parc->r);
return 1;
}
//printf("mid=%f mid=%f \n",midx,midy);
//--------------------------------------------------------------------
//弦矢量的方向角(0-2PI之)
double chordangle=0;//起点到终点的弦向量与x正方向之间的倾斜角
chordangle=acos((x2-x1)/sqrt(pow(x2-x1,2)+pow(y2-y1,2)));
printf("chordangle =%f \n",chordangle);
double amass; //弦向量与X轴正向单位向量的叉积= (y2-y1)k
amass = y2-y1;//由(由(x2-x1)*0-1*(y2-y1))得到
if (amass<0)
{
chordangle=2*PI-chordangle;
//printf("here \n");
}
printf("chordangle =%f \n",chordangle*180/PI);
//---------------------------------------------------------------
double DirectionAngle=0.0;//弦中点到圆心的直线向量的方向角(0-2PI之间)
if ((bulge>0 && arcangle<PI)||(bulge<0 && arcangle>PI))
{
DirectionAngle=chordangle+PI/2;
}
if((bulge<0 && arcangle<PI)||(bulge>0 && arcangle>PI))
{
DirectionAngle=chordangle-PI/2;
}
if(DirectionAngle<0)
{
DirectionAngle=DirectionAngle+2*PI;
}
if (DirectionAngle>2*PI)
{
DirectionAngle= DirectionAngle-2*PI;
}
//---------------------------------------------------------------
double d;//圆心到弦的距离
d=sqrt( radius* radius-chordlength*chordlength/4);
printf("DirectionAngle=%f,chordangle=%f\n",DirectionAngle*180/PI,chordangle*180/PI);
if((-RESOLUTION<(DirectionAngle-0))&&((DirectionAngle-0)<RESOLUTION))
{
cx=midx+d;
cy=midy;
printf("1:cx=%f cy=%f\n ",cx,cy);
}
else
if((-RESOLUTION<(DirectionAngle-PI/2))&&((DirectionAngle-PI/2)<RESOLUTION))
{
cx=midx;
cy=midy+d;
printf("2:cx=%f cy=%f\n ",cx,cy);
}
else
if((-RESOLUTION<(DirectionAngle-PI))&&((DirectionAngle-PI)<RESOLUTION))
{
cx=midx-d;
cy=midy;
printf("3:cx=%f cy=%f\n ",cx,cy);
}
else
if((-RESOLUTION<(DirectionAngle-3*PI/2))&&((DirectionAngle-3*PI/2)<RESOLUTION))
{
cx=midx;
cy=midy-d;
printf("4:cx=%f cy=%f \n ",cx,cy);
}
else
{
double nslope,k;//nslope 为弦的斜率,K为弦中垂线的斜率
double nAngle;//中垂线的倾斜角;
double X,Y; //圆心相对于弦中心点的坐标偏移量
nslope = (y2 - y1) / (x2-x1);
k = -1 / nslope;
nAngle = atan(k) ;
X = fabs(cos(nAngle) * d);
Y = fabs(sin(nAngle) * d);
if (DirectionAngle > PI/2 && DirectionAngle < PI )
{
X = -X;
Y = Y;
}
if (DirectionAngle > PI && DirectionAngle < (PI+PI/2) )
{
X = -X;
Y = -Y;
}
if (DirectionAngle > (PI+PI/2)&& DirectionAngle <2*PI)
{
X = X;
Y = -Y;
}
cx=midx + X;
cy=midy + Y;
printf("cx=%f cy=%f\n ",cx,cy);
}
parc->cx=cx;
parc->cy=cy;
parc->cz=0.0;
parc->r=radius;
printf("x=%lf,y=%lf,z=%lf r=%f \n",parc->cx,parc->cy,parc->cz,parc->r);
return 1;
}
int getArcAngle(PARC parc)//取得圆弧角度
{
double sx(0.0),sy(0.0),ex(0.0),ey(0.0),cx(0.0),cy(0.0),r(0.0);//arc 的起点终 点圆心的坐标
double startangle(0.0),endangle(0.0);
sx=parc->sx;
sy=parc->sy;
ex=parc->ex;
ey=parc->ey;
cx=parc->cx;
cy=parc->cy;
r=parc->r;
//
double num1(0.0),num2(0.0);//x方向矢量和圆心到弧线起点和终点的矢量的叉乘的z 分量
startangle=acos((sx-cx)/r);
num1=sy-cy;
if(num1<0)
{
startangle=2*PI-startangle;
}
printf("startangle =%f \n",startangle*180/PI);
endangle=acos((ex-cx)/r);
num2=ey-cy;
if(num2<0)
{
endangle=2*PI-endangle;
}
printf("endangle =%f \n",endangle*180/PI);
return 0;
}
int main()
{
Point startpoint={119.523,6.29683,0.0} ;
Point endpoint={92.3448,16.3001,0.0} ;
double bulge=-0.607501;
ARC arc1;//={};
getArcR(startpoint ,endpoint ,bulge,&arc1);
getArcAngle(&arc1);
getchar();
return 0;
} 自已网上找到一个,测试过可用
;;参数 pt = 圆弧起点 np = 圆弧终点 gx = 弓弦比
;;返回表 '(圆心 半径)
(defun get_Center (pt np gx / pa bj xc gg rr cp mdp)
(setq pa (angle pt np) ;以弧度为单位返回两点之间连线与当ucs下x轴之间的夹角
bj (* (atan (abs gx)) 4) ;反正切值
xc (* 0.5 (distance pt np)) ;1/2两点间距离
gg (* gx xc)
)
(if (/= 0.0 gg)
(progn ;
(setq rr (/ (+ (* xc xc) (* gg gg)) (* 2 gg)))
(setq cp (polar pt pa xc) ;求点的指定角度,指定距离的点
cp (polar cp (+ pa (/ pi 2)) (- rr gg))
)
(list cp rr) ;组成一个表
)
(list pt 0.0)
)
) gmajvfhpa 发表于 2018-5-10 21:22
自已网上找到一个,测试过可用
虽然看不懂,但还是觉得很厉害~~~今天突然看见公众号上推得lisp AutoCAD 可以用 C 做扩展吗?(以前不知道)只知道可以用 VB 和 lisp. 以前也学过一些 AutoCAD 的 Lisp lisp用来做坐标变换是真的方便 另外lisp语言本身不难,楼主可以自学
页:
[1]