public VectorListOrientation(Curve curve, IList <double> parameters, IList <Vector3d> vectors)
        {
            int N = Math.Min(parameters.Count, vectors.Count);

            m_curve  = curve;
            m_guides = new VectorParameter[N];

            //Plane[] RMFs = curve.GetPerpendicularFrames(parameters);

            //Plane RMF;
            int index = 0;

            for (int i = 0; i < N; ++i)
            {
                if (vectors[i].IsValid && !vectors[i].IsZero)
                {
                    //RMF = curve.GetPerpendicularFrames(new double[] { curve.Domain.Min, parameters[i] })[1];
                    //curve.PerpendicularFrameAt(parameters[i], out RMF);
                    m_guides[index] = new VectorParameter {
                        Direction = vectors[i], Parameter = parameters[i], AngularOffset = double.NaN
                    };
                    m_guides[index].CalculateAngularOffset(curve);
                    index++;
                }
            }

            Array.Resize(ref m_guides, index);

            if (index > 0)
            {
                for (int i = 1; i < index; ++i)
                {
                    double diff = m_guides[i].AngularOffset - m_guides[i - 1].AngularOffset;
                    if (Math.Abs(diff) > Math.PI)
                    {
                        m_guides[i].AngularOffset -= Constants.Tau * Math.Sign(diff);;
                    }

                    /*
                     * if ((m_guides[i].AngularOffset - m_guides[i - 1].AngularOffset) > Math.PI)
                     *  m_guides[i].AngularOffset -= Constants.Tau;
                     * else if ((m_guides[i].AngularOffset - m_guides[i - 1].AngularOffset) < -Math.PI)
                     *  m_guides[i].AngularOffset += Constants.Tau;
                     */
                }
            }
            else
            {
                throw new Exception("No valid vectors or parameters.");
            }

            Array.Sort(m_guides, (a, b) => a.Parameter.CompareTo(b.Parameter));

            RecalculateVectors();
        }
        public override CrossSectionOrientation Join(CrossSectionOrientation orientation)
        {
            if (orientation is VectorListOrientation)
            {
                VectorListOrientation vlo  = orientation as VectorListOrientation;
                VectorParameter[]     temp = new VectorParameter[m_guides.Length + vlo.m_guides.Length];
                Array.Copy(m_guides, temp, m_guides.Length);
                Array.Copy(vlo.m_guides, 0, temp, m_guides.Length, vlo.m_guides.Length);
                Array.Sort(temp, (a, b) => a.Parameter.CompareTo(b.Parameter));

                m_guides = temp;
            }

            return(this.Duplicate());
        }
        public override CrossSectionOrientation[] Split(IList <double> t)
        {
            CrossSectionOrientation[] new_orientations = new CrossSectionOrientation[t.Count + 1];

            if (t.Count < 1)
            {
                new_orientations[0] = this.Duplicate();
                return(new_orientations);
            }

            int    prev       = 0;
            double prev_param = 0.0;
            bool   flag       = false;

            VectorParameter[] new_guides;

            int index = 0;

            foreach (double param in t)
            {
                int res = Array.BinarySearch(m_guides, param);

                if (res < 0)
                {
                    res = ~res;

                    new_guides = new VectorParameter[res - prev + 1];
                    Array.Copy(m_guides, prev, new_guides, 0, res - prev);

                    new_guides[new_guides.Length - 1] = new VectorParameter {
                        Parameter = param, Direction = GetOrientation(m_curve, param)
                    };
                    new_guides[new_guides.Length - 1].CalculateAngularOffset(m_curve);

                    if (prev > 0 || flag)
                    {
                        VectorParameter[] temp = new VectorParameter[new_guides.Length + 1];
                        temp[0] = new VectorParameter {
                            Parameter = prev_param, Direction = GetOrientation(m_curve, prev_param)
                        };
                        temp[0].CalculateAngularOffset(m_curve);

                        Array.Copy(new_guides, 0, temp, 1, new_guides.Length);
                        new_guides = temp;
                    }

                    new_orientations[index] = new VectorListOrientation(
                        m_curve,
                        new_guides);

                    prev_param = param;
                    prev       = res;
                    flag       = true;
                }
                else
                {
                    new_guides = new VectorParameter[res - prev + 1];
                    Array.Copy(m_guides, prev, new_guides, 0, res - prev + 1);

                    new_orientations[index] = new VectorListOrientation(
                        m_curve,
                        new_guides);

                    prev = res;
                }

                index++;
            }

            new_guides = new VectorParameter[m_guides.Length - prev + 1];
            Array.Copy(m_guides, prev, new_guides, 1, m_guides.Length - prev);

            new_guides[0] = new VectorParameter {
                Parameter = t.Last(), Direction = GetOrientation(m_curve, t.Last())
            };
            new_guides[0].CalculateAngularOffset(m_curve);

            new_orientations[index] = new VectorListOrientation(
                m_curve,
                new_guides);

            return(new_orientations);
        }