ObjectARX 足球算法

 

足球有12个五边形和20个六边形,共有60个点,每个点都同时被3个图形所共用。

因此我的画法是(Ojbectarx 2007):

1 先画出底面五边形

2 求出上一层六边形的关键点:具体方法可参考http://www.mjtd.com/Article/ArticleShow.asp?ArticleID=1050

3 通过旋转得到其他四个点,此时就可以画第二层的5个六边形

4由三点确定一个平面,此时就可以画出第三层的5个五边形

5同样的方法可以画出四五六三层的五边形和六边形,此时效果如下:



6第七层和第八层也可以同样画出,不过我先画的第八层,最后是第七层。这样做主要是为了计算方便(参考程序)
最后的效果如下:



在本程序中,我定义了自己的顶点类,MyPoint主要是对点加了个计数器, 这样该程序中总共就由60个点,每个点最大值是3(每个点都同时被3个图形所共用),这样在画图时就能确定哪些点。
下面贴程序:
下载:点击下载此文件 

贴代码:

 

public   class  MyPoint
    
{
        
private Point3d point3d;

        
private int times = 0;//used times,1-3

        
public MyPoint(Point3d point3d)
        
{
            
this.point3d = point3d;
        }


        
public MyPoint(double x,double y,double z)
        
{
            point3d 
= new Point3d(x, y, z);
        }


        
public Point3d Point
        
{
            
get{
                
return point3d;
            }

        }


        
public int Times
        
{
            
get{
                
return this.times;
            }

            
set{
                
this.times = value;
            }

        }

    }

 

 

  public   class  Polygon
    
{
        
protected MyPoint[] mypoint;
        
protected Face[] face = new Face[2];
        
protected Point3d center;
        
protected Vector3d normal;
        
public Polygon(int count)
        
{
            mypoint 
= new MyPoint[count];
        }


        
public Point3d Center
        
{
            
get
            
{
                
return this.center;
            }

        }


        
public Vector3d Normal
        
{
            
get
            
{
                
return this.normal;
            }

        }


        
protected void InitializeFace(Color color)
        
{
            face[
0= new Face(mypoint[0].Point, mypoint[1].Point, mypoint[2].Point, mypoint[3].Point, truetruetruetrue);
            face[
1= new Face(mypoint[3].Point, mypoint[4].Point, mypoint[5 % mypoint.Length].Point, mypoint[6 % mypoint.Length].Point, truetruetruetrue);
            face[
0].Color = color;
            face[
1].Color = color;
            
foreach (MyPoint point in mypoint)
                point.Times
++;
        }


        
public MyPoint GetUsedOncePointNearTo(MyPoint point)
        
{
            MyPoint res 
= null;
            
int num = mypoint.Length;
            
for (int i = 0; i < num; i++)
            
{
                
if (mypoint[i] == point)
                
{
                    
if (mypoint[(i + num - 1% num].Times == 1)
                        res 
= mypoint[(i + num -1% num];
                    
else if (mypoint[(i + 1% num].Times == 1)
                        res 
= mypoint[(i + 1% num];
                    
break;
                }

            }

            
return res;
        }


        
public MyPoint[] GetTwoUsedTwicePoints()
        
{
            MyPoint[] point 
= new MyPoint[2];
            
int i = 0;
            
foreach (MyPoint pt in mypoint)
            
{
                
if (i == 2)
                    
break;
                
if (pt.Times == 2)
                    point[i
++= pt;
            }

            
return point;
        }


        
public bool Contains(MyPoint point)
        
{
            
foreach (MyPoint pt in mypoint)
            
{
                
if (pt == point)
                    
return true;
            }

            
return false;
        }


        
public void AddToDataBase(BlockTableRecord btr, TransactionManager tm)
        
{
            
foreach (Face fa in face)
            
{
                btr.AppendEntity(fa);
                tm.AddNewlyCreatedDBObject(fa, 
true);
            }

        }

    }

 

 

  public   class  Polygon5 : Polygon
    
{

        
//p1,p2,p3 should be in sequence
        public Polygon5(MyPoint p1,MyPoint p2,MyPoint p3)
            :
base(5)
        
{
            InitializeNormalAndCenter(p1, p2, p3);
            mypoint[
0= p1;
            mypoint[
1= p2;
            mypoint[
2= p3;
            
//determine the direction of rotate
            if (p3.Point.RotateBy(Math.PI * 0.4, normal, center) == p2.Point)
            
{
                mypoint[
3= new MyPoint(p3.Point.RotateBy(-Math.PI * 0.4, normal, center));
                mypoint[
4= new MyPoint(p3.Point.RotateBy(-Math.PI * 0.8, normal, center));
            }

            
else{
                mypoint[
3= new MyPoint(p3.Point.RotateBy(Math.PI * 0.4, normal, center));
                mypoint[
4= new MyPoint(p3.Point.RotateBy(Math.PI * 0.8, normal, center));
            }

            InitializeFace(Color.FromRgb(
0,0,0));
        }


        
public Polygon5(MyPoint p1, MyPoint p2, MyPoint p3, MyPoint p4)
            : 
base(5)
        
{
            InitializeNormalAndCenter(p1, p2, p3);
            mypoint[
0= p1;
            mypoint[
1= p2;
            mypoint[
2= p3;
            mypoint[
3= p4;
            
//determine the direction of rotate
            if (p4.Point.RotateBy(Math.PI * 0.4, normal, center) == p3.Point)
            
{
                mypoint[
4= new MyPoint(p4.Point.RotateBy(-Math.PI * 0.4, normal, center));
            }

            
else
            
{
                mypoint[
4= new MyPoint(p4.Point.RotateBy(Math.PI * 0.4, normal, center));
            }

            InitializeFace(Color.FromRgb(
000));
        }


        
public Polygon5(MyPoint[] pointArry)
            : 
base(5)
        
{
            InitializeNormalAndCenter(pointArry[
0], pointArry[1], pointArry[2]);
            
for (int i = 0; i < 5; i++)
                mypoint[i] 
= pointArry[i];
            InitializeFace(Color.FromRgb(
000));
        }


        
public Polygon5(Point3d center, Vector3d normal, Point3d vertex)
            : 
base(5)
        
{
            
this.center = center;
            
this.normal = normal;
            mypoint[
0= new MyPoint(vertex);
            mypoint[
1= new MyPoint(vertex.RotateBy(Math.PI * 0.4, normal, center));
            mypoint[
2= new MyPoint(vertex.RotateBy(Math.PI * 0.8, normal, center));
            mypoint[
3= new MyPoint(vertex.RotateBy(Math.PI * 1.2, normal, center));
            mypoint[
4= new MyPoint(vertex.RotateBy(Math.PI * 1.6, normal, center));

            InitializeFace(Color.FromRgb(
000));
        }


        
private void InitializeNormalAndCenter(MyPoint p1, MyPoint p2, MyPoint p3)
        
{
            Plane plane 
= new Plane(p1.Point, p2.Point, p3.Point);
            normal 
= plane.Normal;

            Vector3d vector12 
= new Vector3d(p2.Point.X - p1.Point.X, p2.Point.Y - p1.Point.Y, p2.Point.Z - p1.Point.Z);
            Vector3d vector12v 
= vector12.RotateBy(Math.PI / 2, normal);
            Line3d line12v 
= new Line3d(
                             
new Point3d((p1.Point.X + p2.Point.X) / 2, (p1.Point.Y + p2.Point.Y) / 2, (p1.Point.Z + p2.Point.Z) / 2),
                             vector12v
                             );

            Vector3d vector23 
= new Vector3d(p2.Point.X - p3.Point.X, p2.Point.Y - p3.Point.Y, p2.Point.Z - p3.Point.Z);
            Vector3d vector23v 
= vector23.RotateBy(Math.PI / 2, normal);
            Line3d line23v 
= new Line3d(
                             
new Point3d((p3.Point.X + p2.Point.X) / 2, (p3.Point.Y + p2.Point.Y) / 2, (p3.Point.Z + p2.Point.Z) / 2),
                             vector23v
                             );
            center 
= line12v.IntersectWith(line23v)[0];
        }



        
public MyPoint GetFootBallPoint()
        
{
            MyPoint p1 
= mypoint[0];
            MyPoint p2 
= mypoint[1];
            MyPoint p3 
= mypoint[2];
            Vector3d vector32 
= new Vector3d(p2.Point.X - p3.Point.X, p2.Point.Y - p3.Point.Y, p2.Point.Z - p3.Point.Z);
            Vector3d vector21 
= new Vector3d(p1.Point.X - p2.Point.X, p1.Point.Y - p2.Point.Y, p1.Point.Z - p2.Point.Z);
            Vector3d curNormal 
= vector32.CrossProduct(vector21);

            Point3d p612 
= p1.Point.RotateBy(-Math.PI * 2 / 3, curNormal,p2.Point);
            Line3d line612 
= new Line3d(p612,
                vector21.RotateBy(Math.PI 
/ 2, curNormal));
            Point3d p12 
= line612.IntersectWith(new Line3d(p1.Point, p2.Point))[0];
            CircularArc3d circle12 
= new CircularArc3d(p12, vector21, p612.DistanceTo(p12));


            Point3d p632 
= p3.Point.RotateBy(Math.PI * 2 / 3, curNormal, p2.Point);
            Line3d line632 
= new Line3d(p632,
                vector32.RotateBy(Math.PI 
/ 2, curNormal));
            Point3d p32 
= line632.IntersectWith(new Line3d(p3.Point, p2.Point))[0];
            CircularArc3d circle32 
= new CircularArc3d(p32, vector32, p632.DistanceTo(p32));

            Point3d point 
= circle12.IntersectWith(circle32)[0];
            
return new MyPoint(point);

           
        }


        
//public Polygon6 CreatePolygon6(MyPoint point)
        
//{
        
//    int[] index = GetNearestTwoPointsIndex(point);
        
//    Polygon6 Polygon6 = new Polygon6(point,mypoint[index[0]],mypoint[index[1]]);
        
//    return Polygon6;
        
//}

        
public MyPoint GetNearestPoint(MyPoint point)
        
{
            
double[] dis = new double[5];
            dis[
0= mypoint[0].Point.DistanceTo(point.Point);
            dis[
1= mypoint[1].Point.DistanceTo(point.Point);
            dis[
2= mypoint[2].Point.DistanceTo(point.Point);
            dis[
3= mypoint[3].Point.DistanceTo(point.Point);
            dis[
4= mypoint[4].Point.DistanceTo(point.Point);

            
int index = 0;
            
for (int i = 1; i < 5; i++)
            
{
                
if (dis[i] < dis[index])
                    index 
= i;
            }

            
return mypoint[index];
        }


        
public MyPoint GetUsedLessThanTwicePointNearTo(MyPoint point)
        
{
            MyPoint res 
= null;
            
for (int i = 0; i < mypoint.Length; i++)
            
{
                
if (mypoint[i] == point)
                
{
                    
//mypoint[(i+4)%5],mypoint[(i+1)%5]
                    if (mypoint[(i + 4% 5].Times <= 2)
                        res 
= mypoint[(i + 4% 5];
                    
else if (mypoint[(i + 1% 5].Times <= 2)
                        res 
= mypoint[(i + 1% 5];
                    
break;
                }

            }

            
return res;
        }


    }

 

 

  public   class  FootBall
    
{
        
private Point3d center;
        
private Point3d vertex;
        
private Vector3d normal;
        
private List<Polygon> polygonList = new List<Polygon>();
        
public FootBall(Point3d center, Point3d vertex, Vector3d normal)
        
{
            
this.center = center;
            
this.vertex = vertex;
            
this.normal = normal;
        }


        
public void Create()
        
{
            Polygon5 polygon5 
= new Polygon5(center, normal, vertex);
            polygonList.Add(polygon5);

            MyPoint[] pointArry 
= new MyPoint[5];
            pointArry[
0= polygon5.GetFootBallPoint();

            pointArry[
1= new MyPoint(pointArry[0].Point.RotateBy(Math.PI * 0.4, polygon5.Normal, polygon5.Center));
            pointArry[
2= new MyPoint(pointArry[0].Point.RotateBy(Math.PI * 0.8, polygon5.Normal, polygon5.Center));
            pointArry[
3= new MyPoint(pointArry[0].Point.RotateBy(Math.PI * 1.2, polygon5.Normal, polygon5.Center));
            pointArry[
4= new MyPoint(pointArry[0].Point.RotateBy(Math.PI * 1.6, polygon5.Normal, polygon5.Center));

            
int i;
            Polygon6[] polygon6 
= new Polygon6[5];
            
for (i = 0; i < pointArry.Length; i++)
            
{
                MyPoint p1 
= pointArry[i];
                MyPoint p4 
= pointArry[(i + 1% pointArry.Length];
                MyPoint p2 
= polygon5.GetNearestPoint(p1);
                MyPoint p3 
= polygon5.GetNearestPoint(p4);
                polygon6[i] 
= new Polygon6(p1, p2, p3, p4);
                polygonList.Add(polygon6[i]);
            }


            Polygon5[] poly5Arry 
= new Polygon5[5];
            
for (i = 0; i < pointArry.Length; i++)
            
{
                
//find pointArry[i] in polygon6[i] and polygon6[(i+4)%5]
                MyPoint p1 = polygon6[i].GetUsedOncePointNearTo(pointArry[i]);
                MyPoint p3 
= polygon6[(i + 4% 5].GetUsedOncePointNearTo(pointArry[i]);
                poly5Arry[i] 
= new Polygon5(p1, pointArry[i], p3);
                polygonList.Add(poly5Arry[i]);
            }


            i 
= 0;
            Polygon6[] polygon62 
= new Polygon6[5];
            
foreach (Polygon6 pol in polygon6)
            
{
                MyPoint[] point2 
= pol.GetTwoUsedTwicePoints();
                MyPoint p1 
= GetPointFromArry5(point2[0], poly5Arry);
                MyPoint p4 
= GetPointFromArry5(point2[1], poly5Arry);
                polygon62[i] 
= new Polygon6(p1, point2[0], point2[1], p4);
                polygonList.Add(polygon62[i
++]);
            }


            i 
= 0;
            Polygon6[] polygon63 
= new Polygon6[5];
            
foreach (Polygon5 poly5 in poly5Arry)
            
{
                MyPoint[] point2 
= poly5.GetTwoUsedTwicePoints();
                MyPoint p1 
= GetPointFromArry6(point2[0], polygon62);
                MyPoint p4 
= GetPointFromArry6(point2[1], polygon62);
                polygon63[i] 
= new Polygon6(p1, point2[0], point2[1], p4);
                polygonList.Add(polygon63[i
++]);
            }


            i 
= 0;
            Polygon5[] poly5Arry2 
= new Polygon5[5];
            
foreach (Polygon6 pol in polygon62)
            
{
                MyPoint[] point2 
= pol.GetTwoUsedTwicePoints();
                MyPoint p1 
= GetPointFromArry6(point2[0], polygon63);
                MyPoint p4 
= GetPointFromArry6(point2[1], polygon63);
                poly5Arry2[i] 
= new Polygon5(p1, point2[0], point2[1], p4);
                polygonList.Add(poly5Arry2[i
++]);
            }


            
//end Polygon5
            Line3d line1 = new Line3d(polygon5.Center, polygon5.Normal);
            Line3d line2 
= new Line3d(poly5Arry[0].Center, poly5Arry[0].Normal);
            Point3d footballCenter 
= line1.IntersectWith(line2)[0];
            Point3d poly5EndCenter 
= footballCenter.Add(
                
new Vector3d(footballCenter.X - polygon5.Center.X,
                             footballCenter.Y 
- polygon5.Center.Y,
                             footballCenter.Z 
- polygon5.Center.Z));
            MyPoint[] point2Arry 
= polygon63[0].GetTwoUsedTwicePoints();
            MyPoint pt1 
= GetPointLessThanTwiceFromArry5(point2Arry[0], poly5Arry2);
            MyPoint pt4 
= GetPointLessThanTwiceFromArry5(point2Arry[1], poly5Arry2);
            Plane plane 
= new Plane(pt1.Point, pt4.Point, point2Arry[0].Point);
            Line3d line3 
= new Line3d(pt1.Point,pt4.Point);
            Line3d line4 
= new Line3d(point2Arry[0].Point,
                                    line3.Direction.RotateBy(Math.PI
/2,plane.Normal));
            Point3d point3d34 
= line4.IntersectWith(line3)[0];
            Point3d poly5OneVertex 
= point3d34.Add(
                
new Vector3d(point3d34.X - point2Arry[0].Point.X,
                             point3d34.Y 
- point2Arry[0].Point.Y,
                             point3d34.Z 
- point2Arry[0].Point.Z));
            Polygon5 polygon5End 
= new Polygon5(poly5EndCenter, normal, poly5OneVertex);
            polygonList.Add(polygon5End);

            
//last Polygon6
            i = 0;
            Polygon6[] polygon64 
= new Polygon6[5];
            
foreach (Polygon6 pol in polygon63)
            
{
                MyPoint[] point2 
= pol.GetTwoUsedTwicePoints();
                MyPoint p1 
= GetPointLessThanTwiceFromArry5(point2[0], poly5Arry2);
                MyPoint p4 
= GetPointLessThanTwiceFromArry5(point2[1], poly5Arry2);
                MyPoint p5 
= polygon5End.GetNearestPoint(p4);
                MyPoint p6 
= polygon5End.GetNearestPoint(p1);
                polygon64[i] 
= new Polygon6(p1, point2[0], point2[1], p4, p5, p6);
                polygonList.Add(polygon64[i
++]);
            }
;
        }


        
public void AddToDataBase(BlockTableRecord btr, TransactionManager tm)
        
{
            
foreach (Polygon poly in polygonList)
                poly.AddToDataBase(btr, tm);
        }


        
private MyPoint[] Get5UsedTwicePoint(Polygon6[] poly6Arry)
        
{
            MyPoint[] pointArry 
= new MyPoint[5];
            
int i = 0;
            
foreach (Polygon6 poly in poly6Arry)
            
{
                
if (i == 5)
                    
break;
                MyPoint[] pt2 
= poly.GetTwoUsedTwicePoints();
                
if (!Contains(pointArry, pt2[0]))
                    pointArry[i
++= pt2[0];
                
if (!Contains(pointArry, pt2[1]))
                    pointArry[i
++= pt2[1];
            }

            
return pointArry;
        }


        
private bool Contains(MyPoint[] pointArry, MyPoint point)
        
{
            
foreach (MyPoint pt in pointArry)
            
{
                
if (pt == point)
                    
return true;
            }

            
return false;
        }


        
private MyPoint GetPointFromArry6(MyPoint point, Polygon6[] poly6Arry)
        
{
            
foreach (Polygon6 poly6 in poly6Arry)
            
{
                
if (poly6.Contains(point))
                
{
                    
return poly6.GetUsedOncePointNearTo(point);
                }

            }

            
return null;
        }


        
private MyPoint GetPointFromArry5(MyPoint point, Polygon5[] poly5Arry)
        
{
            
foreach(Polygon5 poly5 in poly5Arry)
            
{
                
if(poly5.Contains(point))
                
{
                    
return poly5.GetUsedOncePointNearTo(point);
                }

            }

            
return null;
        }


        
private MyPoint GetPointLessThanTwiceFromArry5(MyPoint point, Polygon5[] poly5Arry)
        
{
            
foreach (Polygon5 poly5 in poly5Arry)
            
{
                
if (poly5.Contains(point))
                
{
                    
return poly5.GetUsedLessThanTwicePointNearTo(point);
                }

            }

            
return null;
        }

    }

 

最后是调用代码:

  //  Define Command "AsdkCmd1"
        [CommandMethod( " test " )]
        
static   public   void  test()  //  This method can have any name
         {
            Point3d center;
            Point3d vertex;
            Vector3d normal 
= Vector3d.ZAxis;
            Database db 
= Application.DocumentManager.MdiActiveDocument.Database;

            Editor ed 
= Application.DocumentManager.MdiActiveDocument.Editor;
            PromptPointOptions ptopts 
= new PromptPointOptions("Enter the center:");
            PromptPointResult ptRes 
= ed.GetPoint(ptopts);
            Matrix3d leftSide 
= ed.CurrentUserCoordinateSystem;
            center 
= ptRes.Value.TransformBy(leftSide);

            PromptDoubleOptions pdopts 
= new PromptDoubleOptions("Enter the length of the bottom:");
            PromptDoubleResult pdRes 
= ed.GetDouble(pdopts);
            
double length = pdRes.Value;
            vertex 
= new Point3d(center.X - length, center.Y, center.Z);

            Autodesk.AutoCAD.DatabaseServices.TransactionManager tm 
= db.TransactionManager;
            
using (Transaction trans = tm.StartTransaction())
            
{
                BlockTable bt 
= (BlockTable)
                                   tm.GetObject(db.BlockTableId, OpenMode.ForRead, 
false);

                BlockTableRecord btr 
= (BlockTableRecord)
                tm.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite, 
false);

                FootBall football 
= new FootBall(center, vertex, normal);
                football.Create();
                football.AddToDataBase(btr, tm);
                
//another four Point;
                trans.Commit();
            }

        }

 

over. 有问题联系我.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值