矢量点精度误差

时间:2013-05-24 06:50:40

标签: c# directx

我们的应用程序包含.Net FrameWork3.5和DirectX For Making 2d绘图。 我们坚持精确问题。请给出解决方案来解决精度问题。

我们使用vector3f(向量点)来存储值。而我们在vector3f中存储点的结果只匹配2个精度值。但我们需要5个精度值。

我在这里提到了我的代码..

//功能从Bulge值

中查找ARC参数

polylineVertStart = 6919.602,18951.51,0 polylineVertEnd = 6916.602,18951.51,0

Arc StartPoint = 6919.602,18951.5177,0 Endpoint = 6916.602,18951.51,0

   public static Arc BulgeToArc(PolylineVertex3d polylineVertStart, PolylineVertex3d polylineVertEnd)
    {
        PolylineVertex3d polylineVertex3d = polylineVertEnd;
        PolylineVertex3d polylineVertex3d1 = polylineVertStart; //get previous point

        double x1 = polylineVertex3d1.Position.X;   //Assign start and end points
        double y1 = polylineVertex3d1.Position.Y;
        double x2 = polylineVertex3d.Position.X;
        double y2 = polylineVertex3d.Position.Y;           

        if (y1 == y2)
        {
            y2 += (y1 * 0.0000001);
        }
        if (x1 == x2)
        {
            x2 += (x1 * 0.0000001);
        }

        double bulge = polylineVertex3d1.Bulge;
        double incAngle = 4 * System.Math.Atan(System.Math.Abs(bulge));     //included Angle
        double chord = System.Math.Sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); //Chord length
        double r = 0.5 * chord / System.Math.Cos(0.5 * incAngle - 0.5 * System.Math.PI); //Calculate radius
        double Radius = r;

        double dx = x2 - x1;
        double dy = y2 - y1;

        double slope = dy / dx;     //slope of two points
        double slopeAng = System.Math.Atan(slope);

        if (System.Math.Sign(dy) == -1 && System.Math.Sign(dx) == -1)
        {
            slopeAng = System.Math.PI + slopeAng;
        }
        else if (System.Math.Sign(dy) == -1 && System.Math.Sign(dx) == 1)
        {
            slopeAng = 2 * System.Math.PI + slopeAng;
        }
        else if (System.Math.Sign(dy) == 1 && System.Math.Sign(dx) == -1)
        {
            slopeAng = System.Math.PI + slopeAng;
        }

        double d1 = System.Math.Sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));

        double d2 = d1 / 2;
        double startAng = System.Math.Acos(d2 / r);     //calculate start angle
        double sAngle;


        if (System.Math.Abs(bulge) < 1) //get actual start angle based on bulge direction
        {
            if (System.Math.Sign(bulge) != -1)
            {
                sAngle = slopeAng + startAng;
            }
            else
            {
                sAngle = slopeAng - startAng;
            }

        }
        else
        {
            if (System.Math.Sign(bulge) != -1)
            {
                sAngle = slopeAng - startAng;
            }
            else
            {
                sAngle = slopeAng + startAng;
            }
        }

        double cx = x1 + r * System.Math.Cos(sAngle);
        double cy = y1 + r * System.Math.Sin(sAngle);
        Vector3F Center = new Vector3F((float)cx, (float)cy, 0f);  //calculate center point


        double dx1 = x1 - cx;
        double dx2 = x2 - cx;
        double dy1 = y1 - cy;
        double dy2 = y2 - cy;

        double sAng = System.Math.Atan(dy1 / dx1);
        double eAng = System.Math.Atan(dy2 / dx2);


        if (System.Math.Sign(dy1) == -1 && System.Math.Sign(dx1) == -1)
        {
            sAng = System.Math.PI + sAng;
        }
        else if (System.Math.Sign(dy1) == -1 && System.Math.Sign(dx1) != -1)
        {
            sAng = 2 * System.Math.PI + sAng;
        }
        else if (System.Math.Sign(dx1) == -1)
        {
            sAng = System.Math.PI + sAng;
        }

        if (System.Math.Sign(dy2) == -1 && System.Math.Sign(dx2) == -1)
        {
            eAng = System.Math.PI + eAng;
        }
        else if (System.Math.Sign(dy2) == -1 && System.Math.Sign(dx2) != -1)
        {
            eAng = 2 * System.Math.PI + eAng;
        }
        else if (System.Math.Sign(dx2) == -1)
        {
            eAng = System.Math.PI + eAng;
        }

        double StartAngle;
        double EndAngle;

        if (System.Math.Sign(bulge) != -1)  //finalise start angle and end angle
        {
            StartAngle = sAng;
            EndAngle = eAng;
        }
        else
        {
            StartAngle = eAng;
            EndAngle = sAng;
        }


        Direction dir;
        if (polylineVertStart.Bulge != 0)
            dir = polylineVertStart.Bulge < 0 ? Direction.ClockWise : Direction.CounterClockWise;
        else
            dir = polylineVertEnd.Bulge < 0 ? Direction.ClockWise : Direction.CounterClockWise;

        Arc arc = dir == Direction.ClockWise ? new Arc(Center, new Vector3F(0f, 0f, 1f), Radius, EndAngle, StartAngle, dir) : new Arc(Center, new Vector3F(0f, 0f, 1f), Radius, StartAngle, EndAngle, dir);

        return arc;
    }


  //Function to find ARC from StartAngle,EndAngle,Radius 

     public RenderingEngine.Geometry GetGeomtry()
    {
        RenderingEngine.Geometry geometry = new RenderingEngine.Geometry
                                                {
                                                    EntityPrimitiveType = EntityPrimitiveType.LineStrip
                                                };
        xPoints.Clear();
        yPoints.Clear();
        zPoints.Clear();
        VertexList.Clear();
        List<CustomVertex.PositionColored> vertices = new List<CustomVertex.PositionColored>();

        if (direction == Direction.ClockWise)
        {
            #region clockwise
            double WedgeAngle = 0.0; //clock wise
            if (EndAngle != StartAngle)
            {
                if (EndAngle < StartAngle)
                {
                    WedgeAngle = (StartAngle - EndAngle) / NUMPOINTS;
                }
                else
                {
                    WedgeAngle = ((System.Math.PI * 2) - (EndAngle - StartAngle)) / NUMPOINTS;
                }
            }

            double angle = StartAngle;
            for (int i = 0; i <= NUMPOINTS; i++)
            {
                double theta = angle - (i * WedgeAngle);
                double x = center.X + (radius * SystemMath.Cos(theta));
                double y = center.Y + (radius * SystemMath.Sin(theta));
                double z = center.Z;

                CustomVertex.PositionColored positionColored = new CustomVertex.PositionColored
                                                                   {
                                                                       Position =
                                                                           new Vector3((float) x, (float) y,
                                                                                       (float) z),
                                                                       Color = Color.ToArgb()
                                                                   };
                vertices.Add(positionColored);

                xPoints.Add((float)x);
                yPoints.Add((float)y);
                zPoints.Add((float)z);
                VertexList.Add(new Vector3F((float)x, (float)y, (float)z));
            }

            double startx = Center.X + (Radius * System.Math.Cos(StartAngle));
            double starty = Center.Y + (Radius * System.Math.Sin(StartAngle));
            double startz = Center.Z;
            double endx = Center.X + (Radius * System.Math.Cos(EndAngle));
            double endy = Center.Y + (Radius * System.Math.Sin(EndAngle));
            double endz = Center.Z;
            startPoint = new Vector3F((float)startx, (float)starty, (float)startz);
            endPoint = new Vector3F((float)endx, (float)endy, (float)endz);
            #endregion clockwise
        }
        else
        {
            #region Counter ClockWise

            double WedgeAngle = 0.0;
            if (EndAngle != StartAngle)
            {
                if (EndAngle > StartAngle)
                {
                    WedgeAngle = (EndAngle - StartAngle) / NUMPOINTS;
                }
                else
                {
                    WedgeAngle = ((System.Math.PI * 2 - StartAngle) + EndAngle) / NUMPOINTS;
                }
            }
            double angle = StartAngle;
            for (int i = 0; i <= NUMPOINTS; i++)
            {
                double theta = angle + (i * WedgeAngle);
                double x = center.X + (radius * SystemMath.Cos(theta));
                double y = center.Y + (radius * SystemMath.Sin(theta));
                double z = center.Z;


                CustomVertex.PositionColored positionColored = new CustomVertex.PositionColored
                                                                   {
                                                                       Position =
                                                                           new Vector3((float) x, (float) y,
                                                                                       (float) z),
                                                                       Color = Color.ToArgb()
                                                                   };
                vertices.Add(positionColored);

                xPoints.Add((float)x);
                yPoints.Add((float)y);
                zPoints.Add((float)z);
                VertexList.Add(new Vector3F((float)x, (float)y, (float)z));
            }

            double startx = Center.X + (Radius * System.Math.Cos(StartAngle));
            double starty = Center.Y + (Radius * System.Math.Sin(StartAngle));
            double startz = Center.Z;
            double endx = Center.X + (Radius * System.Math.Cos(EndAngle));
            double endy = Center.Y + (Radius * System.Math.Sin(EndAngle));
            double endz = Center.Z;
            startPoint = new Vector3F((float)startx, (float)starty, (float)startz);
            endPoint = new Vector3F((float)endx, (float)endy, (float)endz);
            #endregion
        }
        geometry.Vertices.Add(vertices);

        return geometry;
    }


 Here arc start point and endpoint x value always come correctly but y value is some precision problem.

先谢谢..

0 个答案:

没有答案