highflybird 发表于 2012-6-6 00:30:31

本帖最后由 highflybird 于 2012-6-6 10:55 编辑

关于椭圆的OCS是这样计算的:
设椭圆中心坐标为cen,长轴矢量是maj,法线矢量是nrm --这里是(0 0 -1)
那么你这个题目中由长轴矢量 的单位矢量 XDir是:(0.134264 0.990946 0.0)
那么短轴的单位矢量是: nrm跟 XDir的叉积:(0.990946 -0.134264 0.0)
因而这个椭圆自身的OCS变换矩阵mat是:
|0.134264 0.9909460.0|
|0.990946 -0.134264 0.0|
|0      0         -1.|
注意了,在计算的时候矩阵要倒置一下。即:
|XDir.xYDir.xZDir.x|
|XDir.yyDir.yZDir.y|
|XDir.zyDir.zZDir.z|
因而对于椭圆的起始角度可以算出:
由初始点: (340.122 * cos(2.35439) 340.122*0.9999999999977266*sin(2.35439) 0) = (-240.069 240.936 0)
进行上面的矩阵变换得到新的点。
(mat x (-240.069 240.936 0)) = (206.522 -270.244 0.0)
最后加上椭圆的中心,相当于平移: (3217176.6902 532617.0907 0)
这样就得到坐标的端点。
(3217383.2119 532346.8465 0)
这个坐标是块内坐标,
然后把这个坐标通过图块的变换矩阵变换到WCS(世界坐标系)这样就得到解了。
对于椭圆的长轴矢量,也可以由椭圆的中心加上长轴矢量,就是长轴端点,然后把椭圆的中心和长轴端点的块内坐标
再次乘图块的变换矩阵,分别得到世界坐标系统的椭圆中心和长轴端点坐标,把WCS下的长轴端点坐标减去椭圆中心坐标
这样就得到椭圆的WCS下的长轴矢量。
不知道这样说你是否理解了?

highflybird 发表于 2012-6-6 00:55:43

本帖最后由 highflybird 于 2012-6-6 02:09 编辑

另外要说的一点,一个图块炸开后和没炸开后,里面的东西有可能不一样的。譬如你这个图就是这样。
没炸开前的椭圆的参数和炸开后的椭圆的参数不同。

lzz0517 发表于 2012-6-6 10:52:52

如果要求出块炸开的椭圆弧的起始角度和终止角度,没有长轴矢量坐标的话,好像没别的办法可以求出角度了,因为我用炸开块后的椭圆弧的参数进行求角度,得到的角度就是CAD上面显示的角度,用的办法如下:http://blog.csdn.net/ymain/article/details/6225722;其中的参数为长轴矢量坐标,起点矢量坐标,这两个参数代入getRotateAngle函数求出起始角度,长轴矢量坐标,端点矢量坐标,这两个参数代入getRotateAngle函数求出端点角度。

问题是现在不知道怎么求出这个长轴矢量坐标!

如果用余弦定理求夹角,也还是要知道起点或端点与圆心的连线跟圆心左边的长轴端点坐标的夹角还是右边的夹角,所以要求角度总绕不开长轴矢量坐标!

highflybird 发表于 2012-6-6 10:59:45

lzz0517 发表于 2012-6-6 10:52 static/image/common/back.gif
如果要求出块炸开的椭圆弧的起始角度和终止角度,没有长轴矢量坐标的话,好像没别的办法可以求出角度了,因 ...

我现在已经在70楼做了修改。请回看。

highflybird 发表于 2012-6-6 11:04:36

另外,如果不是用CAD编程里面的函数,那么你用C#如何创建一个椭圆的?
能否把函数原型写出来?或者这段代码写出来?

lzz0517 发表于 2012-6-6 11:50:05

我用来画倾斜椭圆弧函数如下:
void drawellipsearc(double x,double y,double sa,double ea,double rotateangle,double R,double r)
{
    if(sa>ea)
      ea+=2*PI;
   List<PointF> listpoint=new List<PointF>();
   for(int i=0;i<65;i++)
{
    double angle=sa+i*(ea-sa)/64;
   double x=R*cos(angle);
   double y=r*sin(angle);
   double nx=x*cos(rotateangle)-y*sin(rotateangle)+x;
   double ny=y*cos(rotateangle)+x*sin(rotateangle)+y;
   PointF p=new PointF((float)nx,(float)ny);
   listpoint.add(p);
}
listpoint.add(listpoint);
Pen pen = new Pen(Color.Black, 3);
Graphics.DrawLines(pen, listpoint.ToArray());}

lzz0517 发表于 2012-6-6 11:50:43

highflybird 发表于 2012-6-6 10:59 static/image/common/back.gif
我现在已经在70楼做了修改。请回看。

你说那个是不是用来求长轴矢量的呢,我今天看了一下没看明白怎么用!

highflybird 发表于 2012-6-6 12:52:42

lzz0517 发表于 2012-6-6 11:50 static/image/common/back.gif
你说那个是不是用来求长轴矢量的呢,我今天看了一下没看明白怎么用!

楼主再仔细看看70楼最后一段话。
首先求出椭圆在块内的长轴端点 和椭圆中心
把这两点通过插入块的变换矩阵,映射到世界坐标系中,那么不就得到了椭圆的在世界坐标系下的长轴矢量了吗?

highflybird 发表于 2012-6-6 12:56:14

如果楼主是用线段来模拟椭圆的,那为何不求出椭圆在块内的各分点的坐标呢?然后变换到世界坐标系就是了,最后把这些点用线段连起来。
不过要问一下:为什么不用RotateTransform 等C#中的矩阵变换函数对图像进行变换呢?

lzz0517 发表于 2012-6-6 14:58:24

本帖最后由 lzz0517 于 2012-6-6 14:59 编辑

你看看我步骤有没有错,我用了你说的计算椭圆长轴矢量的方法进行计算,但与CAD上进行比较后,对不上CAD上的值:
double ix=-399474.1637001187;//插入点X
   double iy=3238438.33505016;   //插入点Y
   double scalex=-1.0;//缩放比例X
   double scaley=1.0;//缩放比例Y
   double angle=106.4911716322804*Math.PI/180; //插入点旋转弧度
   double ox=3217926.635124058; //块坐标系的圆心X
   double oy=532617.0907392278; //块坐标系的圆心Y
   double lrx=45.66621877367426; // 长轴端点X
   double lry=337.0426302735758;//长轴端点Y
   double ratio=0.9999999999977266;//半径比例
   double sa=2.35439212168697;   // 起始弧度
   double ea=3.641394339275362;// 终止弧度
   
   //计算椭圆弧的长轴矢量坐标
double x=ox+lrx;
   double y=oy+lry;
   double nx=ix+x*Math.Cos(angle)*scalex-y*Math.Sin(angle)*scaley;
   double ny=iy+y*Math.Cos(angle)*scaley+x*Math.Sin(angle)*scalex;
//计算得到的长轴端点坐标X=2973.66024679359,Y=1553.78513403563
   Console.WriteLine("长轴端点坐标X={0},Y={1}",nx,ny);
   double nox=ix+ox*Math.Cos(angle)*scalex-oy*Math.Sin(angle)*scaley;
   double noy=iy+oy*Math.Cos(angle)*scaley+ox*Math.Sin(angle)*scalex;
// 计算得到的圆心坐标X=3283.87495806016,Y=1693.24828713574
    double Vx=nx-nox;
   double Vy=ny-noy;
//这是计算得到长轴矢量坐标X=-310.21471126657,Y=-139.463153100107

   //CAD上显示的圆心和长轴矢量坐标
   //圆心X=3283.875,Y=1693.2483
   //长轴矢量坐标X=318.3132,Y=119.8326
页: 1 2 3 4 5 6 7 [8] 9 10 11
查看完整版本: 椭圆弧旋转后计算角度问题