Example #1
0
        private void AddMitre(MitreInfo Mitre)
        {
            if (Mitre.bNoMitre)
                return;

            int idxbase = mPts.Count;
            double angle = Point3D.DihedralAngle(Mitre.B, Mitre.Q, Mitre.C);
            int count = (int)(angle * 180.0 / Math.PI / 20.0);
            if (count < 1)
                count = 1;
            Point3D newpt;
            for (int i = 0; i <= count; i++)
            {
                newpt = i * (Mitre.B - Mitre.Q) + (count - i) * (Mitre.C - Mitre.Q);
                newpt.R = (Mitre.B - Mitre.Q).R;
                newpt += Mitre.Q;
                newpt.R = mRadius + mHalfLineHeight;
                AddPoint(newpt);
                AddPoint(newpt.ScaledTo(mRadius - mHalfLineHeight));
            }
            newpt = Mitre.A;
            newpt.R = mRadius + mHalfLineHeight;
            AddPoint(newpt);
            AddPoint(newpt.ScaledTo(mRadius - mHalfLineHeight));

            // vertices from B to C is at idxbase+n*2, for N = 0..count
            // vertices from B' to C' is at idxbase+n*2+1 for N=0..count
            // vertex A is at idxbase+2*count+2
            // vertex A' is at idxbase+2*count+3
            Point3D inside = Mitre.Q.ScaledTo(mRadius);
            for (int n = 0; n < count; n++)
            {
                AddFace(idxbase + n * 2, idxbase + (n + 1) * 2, idxbase + count * 2 + 2, inside);  //N,N+1,A
                AddFace(idxbase + n * 2 + 1, idxbase + (n + 1) * 2 + 1, idxbase + count * 2 + 3, inside);  //N',N'+1,A'
                AddFace(idxbase + n * 2, idxbase + (n + 1) * 2, idxbase + n * 2 + 1, inside); //N, N+1, N'
                AddFace(idxbase + (n + 1) * 2, idxbase + n * 2 + 1, idxbase + (n + 1) * 2 + 1, inside); //N+1, N', N' + 1
            }
        }
Example #2
0
        public Tour(string Filename, double Radius, double HalfLineWidth, double HalfLineHeight)
        {
            mRadius = Radius;
            mHalfLineWidth = HalfLineWidth;
            mHalfLineHeight = HalfLineHeight;

            /*
             * Read in Tour
             */
            List<Point3D> TourPoints = new List<Point3D>();
            StreamReader sr = new StreamReader(Filename);
            while (!sr.EndOfStream)
            {
                string LineIn = sr.ReadLine();
                char[] comma = { ',' };
                string[] StringsIn = LineIn.Split(comma);
                if (StringsIn.Count<string>() < 3) continue;

                TourPoints.Add(new Point3D(double.Parse(StringsIn[0]),
                                            double.Parse(StringsIn[1]),
                                            double.Parse(StringsIn[2])).ScaledTo(mRadius));
            }
            sr.Close();

            //build the mitres:
            mMitres = new List<MitreInfo>();
            int prev = -1;
            int next = 1;
            int current = 0;
            while (current < TourPoints.Count )
            {
                MitreInfo NewMitre = null;

                while (NewMitre == null || NewMitre.bDegenerate)
                {
                    if( NewMitre != null )
                    {
                        if( NewMitre.bDegenerateBoth )
                        {
                            //both sides bad, delete this one.
                            NewMitre = null;
                            current = next;
                            next++;
                        }
                        else if( NewMitre.bDegenerateBackward )
                        {
                            mMitres.Remove(mMitres.Last());
                            prev--;
                        }
                        else // NewMitre.bDegenerateForward
                        {
                            next++;
                        }
                    }
                    NewMitre = new MitreInfo(TourPoints[(prev + TourPoints.Count) % TourPoints.Count],
                                              TourPoints[current],
                                              TourPoints[next % TourPoints.Count],
                                              HalfLineWidth);
                }
                mMitres.Add(NewMitre);

                prev = current;
                current = next;
                next++;
            }

            /*
             * add points and faces.
             */
            for (current = 0; current < mMitres.Count; current++)
            {
                next = (current + 1) % mMitres.Count;
                AddMitre(mMitres[current]);
                AddEdge(mMitres[current], mMitres[next]);
            }
        }
Example #3
0
        private void AddEdge(MitreInfo Start, MitreInfo End)
        {
            //new variables for manipulation and reorganizing, A is the start, B is the end Left and Right really have no meaning other than to distinguish sides
            Point3D SL = Start.A;  //StartLeft
            Point3D SR = Start.C;  //StartRight
            Point3D EL = End.A;    //EndLeft
            Point3D ER = End.B;    //EndRight

            //swap the End if necessary
            if ((SL - EL).R + (SR - ER).R >
                (SL - ER).R + (SR - EL).R)
            {
                EL = End.B;
                ER = End.A;
            }

            //minangle that each step sweeps out ensures that the (sphere height) above the middle of a face doesn't dip below 99% of the height at the face edge.
            double minangle = 2.0 * Math.Acos((mRadius + 0.99 * mHalfLineHeight) / (mRadius + mHalfLineHeight));

            //from this we calculate how many steps this edge will take.
            int count = (int)(Math.Max(Point3D.Angle(SL, Point3D.Origin, EL),
                                       Point3D.Angle(SR, Point3D.Origin, ER)) /
                              minangle +
                              0.5);
            if (count == 0) count = 1;

            //prepare for laying down the points and triangles.
            int idxbase = mPts.Count;

            for (int n = 0; n <= count; n++)
            {
                //add the next 4 pts: NL, N'L, NR, N'R
                Point3D newpt = (count - n) * SL + n * EL;
                newpt.R = mRadius + mHalfLineHeight;
                AddPoint(newpt);
                AddPoint(newpt.ScaledTo(mRadius - mHalfLineHeight));

                newpt = (count - n) * SR + n * ER;
                newpt.R = mRadius + mHalfLineHeight;
                AddPoint(newpt);
                AddPoint(newpt.ScaledTo(mRadius - mHalfLineHeight));
            }

            //pts from SL to EL are idxbase + N*4 for for N = 0..count
            //pts from S'L to E'L are idxbase + N*4+1 for for N = 0..count
            //pts from SR to ER are idxbase + N*4+2 for for N = 0..count
            //pts from S'R to E'R are idxbase + N*4+3 for for N = 0..count
            for (int n = 0; n < count; n++)
            {
                Point3D inside = (mPts[idxbase + n * 4] + mPts[idxbase+n*4+2]).ScaledTo(mRadius);

                AddFace(idxbase + (n + 1) * 4, idxbase + n * 4 + 1, idxbase + n * 4, inside); //N+1L, N'L, NL,
                AddFace(idxbase + (n + 1) * 4, idxbase + n * 4 + 1, idxbase + (n + 1) * 4 + 1, inside); //N+1L, N'L, N+1'L

                AddFace(idxbase + (n + 1) * 4 + 2, idxbase + n * 4 + 3, idxbase + n * 4 + 2, inside); //N+1R, N'R, NR
                AddFace(idxbase + (n + 1) * 4 + 2, idxbase + n * 4 + 3, idxbase + (n + 1) * 4 + 3, inside); //N+1R, N'R, N+1'R

                AddFace(idxbase + (n + 1) * 4, idxbase + n * 4 + 2, idxbase + n * 4, inside); //N+1L, NR, NL
                AddFace(idxbase + (n + 1) * 4, idxbase + n * 4 + 2, idxbase + (n + 1) * 4 + 2, inside); //N+1L, NR, N+1R

                AddFace(idxbase + (n + 1) * 4 + 1, idxbase + n * 4 + 3, idxbase + n * 4 + 1, inside); //N+1'L, N'R, N'L
                AddFace(idxbase + (n + 1) * 4 + 1, idxbase + n * 4 + 3, idxbase + (n + 1) * 4 + 3, inside); //N+1'L, N'R, N+1'R
            }
        }