示例#1
0
 public Rotation(Rotation A)
 {
     mQ0 = A.Q0;
     mQX = A.QX;
     mQY = A.QY;
     mQZ = A.QZ;
 }
示例#2
0
        public Cylinder(Point3D Center, Point3D Direction, double Height, double Radius, int nPoints)
        {
            //create cylinder centered at 0, along z axis, with given length and radius.
            for (int i = 0; i < nPoints; i++)
            {
                AddPoint(Point3D.FromCylindricalCoords(Radius, Height / 2.0, Math.PI * 2.0 * ((double)i / nPoints)));
                AddPoint(Point3D.FromCylindricalCoords(Radius, -Height / 2.0, Math.PI * 2.0 * ((double)i / nPoints)));
            }
            AddPoint(new Point3D(0, 0, Height / 2.0));
            AddPoint(new Point3D(0, 0, -Height / 2.0));

            //add faces
            for (int i = 0; i < nPoints; i++)
            {
                int next = (i + 1) % nPoints;
                AddFace(nPoints, i * 2, next * 2, Point3D.Origin);
                AddFace(nPoints + 1, i * 2 + 1, next * 2 + 1, Point3D.Origin);
                AddFace(next * 2, i * 2 + 1, i * 2, Point3D.Origin);
                AddFace(next * 2, i * 2 + 1, next * 2 + 1, Point3D.Origin);
            }

            if (Radius < 0)
            {
                foreach (Triangle tri in mFaces)
                    tri.Reverse();
            }

            //transform points
            if (Direction.R > DMS.EPSILON && Direction.Phi > DMS.EPSILON)
            {
                Rotation rot = new Rotation(Direction.Normalized.Phi,
                                             new Point3D(-Direction.Y, Direction.X, 0));
                for (int i = 0; i < mPts.Count(); i++)
                {
                    mPts[i] = rot.Rotate(mPts[i]);
                }
            }

            //add offset
            for (int i = 0; i < mPts.Count(); i++)
            {
                mPts[i] += Center;
            }
        }
示例#3
0
        private Point3D JitterPt(Point3D pt)
        {
            double oneminuscosjitterradius = 1.0 - Math.Cos(m_JitterRadius * GetGreyValue(pt));
            //First we get a random point within spherical cap centered at (0,0,1) with a radius of max
            Point3D jitteredpt = Point3D.FromSphericalCoords(1.0,
                                                             Math.Acos(1.0 - m_rand.NextDouble() * oneminuscosjitterradius),
                                                             m_rand.NextDouble() * 2.0 * Math.PI );

            Rotation ToPt = new Rotation(pt.Theta, pt.Phi, 0);
            return ToPt.Rotate( jitteredpt );
        }
示例#4
0
        public void DrawImage(String filename, bool bSpline, bool bColors, bool bRotate90, double scale )
        {
            Bitmap newimage = new Bitmap(4000, 2000);
            Graphics g = Graphics.FromImage(newimage);
            g.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, newimage.Width, newimage.Height ) );

            Point2D ImageScale = new Point2D(newimage.Width / (2.0 * Math.PI), newimage.Height / Math.PI);
            const int pieces = 10;

            Rotation rot = Rotation.Identity;
            if (bRotate90)
            {
                rot = new Rotation(Math.PI / 2.0, Point3D.YAxis);
                for (int i = 0; i < m_Cities.Count; i++)
                {
                    m_Cities[i] = rot.Rotate(m_Cities[i]);
                }
            }

            for (int i = 0; i < m_Cities.Count; i++)
            {
                List<Point3D> interp = Interpolate(i, pieces, bSpline);
                for (int j = 0; j < pieces; j++)
                {
                    double progress = ((double)i + (double)j / pieces) / m_Cities.Count;
                    Color color = bColors ? Color.FromArgb((int)(progress * 255.0), 0, 128) : Color.Black;

                    Point3D A = interp[j];
                    Point3D B = interp[j + 1];

                    double greyscale = GetGreyValue((-rot).Rotate(A));
                    Point2D AvgSize = new Point2D(1.0 / Math.Sin(A.Phi), 1.0) * scale * ((greyscale - 0.1) / -0.9 + 2.0);

                    Point2D delta = new Point2D( A.Theta - B.Theta, A.Phi - B.Phi );
                    DMSCore.FixAngle(delta.X);

                    g.FillEllipse( new SolidBrush(color),
                                   (float)((A.Theta + Math.PI - AvgSize.X * 0.5) * ImageScale.X),
                                   (float)((A.Phi - AvgSize.Y * 0.5) * ImageScale.Y),
                                   (float)(AvgSize.X * ImageScale.X),
                                   (float)(AvgSize.Y * ImageScale.Y) );

                    double thickness = Math.Sqrt(Math.Cos(delta.Theta) * AvgSize.Y * Math.Cos(delta.Theta) * AvgSize.Y +
                                                 Math.Sin(delta.Theta) * AvgSize.X * Math.Sin(delta.Theta) * AvgSize.X ) *
                                       ImageScale.X;

                    if (Math.Abs(A.Theta - B.Theta) < Math.PI)
                    {
                        g.DrawLine(new Pen(color, (float)thickness),
                                   (float)((A.Theta + Math.PI) * ImageScale.X),
                                   (float)(A.Phi * ImageScale.Y),
                                   (float)((B.Theta + Math.PI) * ImageScale.X),
                                   (float)(B.Phi * ImageScale.Y));
                    }
                    else if (A.Theta > 0.0)
                    {
                        g.DrawLine(new Pen(color, (float)thickness),
                                   (float)((A.Theta - Math.PI) * ImageScale.X),
                                   (float)(A.Phi * ImageScale.Y),
                                   (float)((B.Theta + Math.PI) * ImageScale.X),
                                   (float)(B.Phi * ImageScale.Y));
                        g.DrawLine(new Pen(color, (float)thickness),
                                   (float)((A.Theta + Math.PI) * ImageScale.X),
                                   (float)(A.Phi * ImageScale.Y),
                                   (float)((B.Theta + 3.0 * Math.PI) * ImageScale.X),
                                   (float)(B.Phi * ImageScale.Y));
                    }
                    else
                    {
                        g.DrawLine(new Pen(color, (float)thickness),
                                   (float)((A.Theta + Math.PI) * ImageScale.X),
                                   (float)(A.Phi * ImageScale.Y),
                                   (float)((B.Theta - Math.PI) * ImageScale.X),
                                   (float)(B.Phi * ImageScale.Y));
                        g.DrawLine(new Pen(color, (float)thickness),
                                   (float)((A.Theta + 3.0 * Math.PI) * ImageScale.X),
                                   (float)(A.Phi * ImageScale.Y),
                                   (float)((B.Theta + Math.PI) * ImageScale.X),
                                   (float)(B.Phi * ImageScale.Y));
                    }

                }
            }

            newimage.Save(filename);
        }
示例#5
0
        public override Color GetPixel(int x, int y)
        {
            double X = (double)x / Math.Min(m_Size.Height, m_Size.Width);
            double Y = (double)y / Math.Min(m_Size.Height, m_Size.Width);

            Point2D UV = m_Net.Map( new Point2D(X - (int)X, Y - (int)Y ) );
            if( UV == null )
                return m_Blank;

            #if false //sierpinski hack
            //get a sense of scale:
            double X2 =  (double)(x + ((x>0)?-1:1)) / Math.Min(m_Size.Height, m_Size.Width);
            Point2D UV2 = m_Net.Map(new Point2D(X2 - (int)X2, Y - (int)Y));
            int nNumHops = -(int)Math.Log( (UV - UV2).R * m_Size.Width, 2.0);

            for( int i=0; i<nNumHops; i++ )
            {
                Point2D A = new Point2D(-1, -1);
                Point2D B = new Point2D(1, -1);
                Point2D C = new Point2D(0, Math.Sqrt(3) - 1.0);

                if ((UV - A).R < (UV - (B + C) / 2).R) //hop away from A
                    UV = A + 2.0 * (UV - A);
                else if ((UV - B).R < (UV - (A + C) / 2).R)
                    UV = B + 2.0 * (UV - B);//hop away from B
                else if ((UV - C).R < (UV - (A + B) / 2).R)
                    UV = C + 2.0 * (UV - C);//hop away from C
                else
                    break;

            }
            #endif

            switch( m_Xfrm )
            {
                case XfrmMode.Stereographic:
                    Point3D SpherePoint = UV.InvStereographicToSphere(); //unit disc converted to southern hemisphere.

                    if ((Math.Truncate(X) + Math.Truncate(Y)) % 2 > 0)
                    {
                        SpherePoint.Z *= -1.0;  //puts it into the northern hemisphere.
                        SpherePoint.X *= -1.0;  //makes things not mirrored.
                    }

                    //rotate southern hemisphere to be centered on y-axis in such a way to make the final result pretty.
                    Rotation rot = new Rotation(Math.PI, new Point3D(0, -1.0, 1.0));
                    SpherePoint = rot.Rotate(SpherePoint);

                    return m_Source.GetSpherePixel(tweak.Rotate(SpherePoint));

                case XfrmMode.Lagrange:
                    //UV: unit disc
                    SpherePoint = UV.InvStereographicToSphere();   // convert to southern hemisphere (z<0)

                    //rotate southern hemisphere to be centered on y-axis in such a way to make the final result pretty.
                    rot = new Rotation(Math.PI, new Point3D(0, -1.0, 1.0));
                    SpherePoint = rot.Rotate(SpherePoint);

                    //mercator map is centered on y axis:
                    Point2D Merc = SpherePoint.Mercator();  //that unit circle is now (x,y)=(+/-PI/2, +/-inf) and in conformal space.
                    Merc *= 2.0;  //and now it covers (x,y) = (+/-PI, +/-inf)
                    SpherePoint = Point3D.FromMercator(Merc); //now unit circle covers the entire sphere, centered on x axis.

                    return m_Source.GetSpherePixel(tweak.Rotate(SpherePoint));

                case XfrmMode.None:
                    return m_Source.GetPixel((UV + new Point2D(1.0, 1.0)) * 0.5);

                case XfrmMode.Quasiconformal:
                    //calculate the offset
                    double grayvalue = m_Net.Quasiconformality( new Point2D(X - (int)X, Y - (int)Y ) );
                    grayvalue -= 1.0;  //we're going from 1
                    grayvalue /= 3.0;  //... to 3
                    grayvalue *= 255.0;
                    if( grayvalue > 255.0 ||  grayvalue < 0.0 )
                        grayvalue = 255.0;
                    return Color.FromArgb((int)grayvalue, (int)grayvalue, (int)grayvalue);
            }

            //if we're here I don't know what's gone wrong.
            return BlankColor;
        }
示例#6
0
            public Rotation rot; // orientation on sphere

            #endregion Fields

            #region Constructors

            public TurtleState(Point2D p, Point2D d, Rotation r)
            {
                pos = p; dir = d; rot = r;
            }
示例#7
0
 public Segment(Rotation AonSphere, Point2D AonPlane, Point2D BonPlane)
     : this(AonSphere, AonPlane, BonPlane, 1.0)
 {
 }
示例#8
0
 public Segment(Rotation AonSphere, Point2D AonPlane, Point2D BonPlane, double Strength )
     : this(AonSphere, AonPlane, BonPlane, Strength, false)
 {
 }
示例#9
0
        public Segment( Rotation AonSphere, Point2D AonPlane, Point2D BonPlane, double Strength, bool bZeroLength )
        {
            m_Arot = AonSphere;
            m_A = AonPlane;
            m_B = BonPlane;
            m_Strength = Strength;

            m_AtoBDir = (m_B - m_A).Normalized;
            if (bZeroLength) m_B = m_A;
            m_Length = (m_B - m_A).R;
        }
示例#10
0
 public Transform(Transform A)
 {
     m_rotation = new Rotation(A.rotation);
     m_translation = new Point3D(A.translation);
 }
示例#11
0
 public Transform(Rotation rotation, Point3D translation)
 {
     m_rotation = rotation;
     m_translation = translation;
 }
示例#12
0
 public Transform()
 {
     m_rotation = new Rotation();
     m_translation = new Point3D();
 }