private IPolyline6 ConstructSpiralbyDeltaAngle(IPoint theFromPoint, IPoint theTangentpoint, double theFromCurvature,
                                                       double theToCurvature, bool isCCW, double theSpiralDeltaAngle, esriCurveDensifyMethod DensifyMethod, double theCurveDensity, out double ExitTangent)
        {
            //the parameter name "curvature" is actually the inverse of the radius. Infinity radius is 0 curvature.
            ExitTangent = 0;
            IPolyline6 thePolyLine = new PolylineClass() as IPolyline6;

            try
            {
                IGeometryEnvironment4 theGeometryEnvironment = new GeometryEnvironmentClass();
                IConstructClothoid    TheSpiralConstruction  = theGeometryEnvironment as IConstructClothoid;
                thePolyLine = TheSpiralConstruction.ConstructClothoidByAngle(theFromPoint, theTangentpoint, isCCW,
                                                                             theFromCurvature, theToCurvature, theSpiralDeltaAngle, DensifyMethod, theCurveDensity) as IPolyline6;

                //now use the Query on the same Spiral, to get the precise exit tangent
                double dCurvature;
                double dSplitLength;
                double dSplitAngle;
                ILine  pExitTangentLine;

                if (thePolyLine != null)
                {
                    TheSpiralConstruction.ConstructSplitClothoidByAngle(thePolyLine.ToPoint, theFromPoint,
                                                                        theTangentpoint, isCCW, theFromCurvature, theToCurvature, theSpiralDeltaAngle,
                                                                        out dCurvature, out dSplitLength, out dSplitAngle, out pExitTangentLine);

                    ExitTangent = pExitTangentLine.Angle; //returns polar azimuth in radians
                }

                return(thePolyLine);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return(null);
            }
        }
        private IPolyline6 ConstructSpiralbyLength(IPoint theFromPoint, IPoint theTangentpoint, double theFromCurvature,
                                                   double theToCurvature, bool isCCW, double theSpiralLength, esriCurveDensifyMethod DensifyMethod, double theCurveDensity, out double ExitTangent)
        {
            //the parameter name "curvature" is the inverse of the radius. Infinity radius is 0 radius.
            ExitTangent = 0;
            IPolyline6 thePolyLine = new PolylineClass() as IPolyline6;

            try
            {
                IGeometryEnvironment4 theGeometryEnvironment = new GeometryEnvironmentClass();
                IConstructClothoid    TheSpiralConstruction  = theGeometryEnvironment as IConstructClothoid;
                thePolyLine = TheSpiralConstruction.ConstructClothoidByLength(theFromPoint, theTangentpoint, isCCW,
                                                                              theFromCurvature, theToCurvature, theSpiralLength, DensifyMethod, theCurveDensity) as IPolyline6;

                //now use the Query on the same Spiral, to get the precise exit tangent
                double dCurvature;
                double dSplitLength;
                double dSplitAngle;
                ILine  pExitTangentLine;
                if (thePolyLine != null)
                {
                    TheSpiralConstruction.ConstructSplitClothoidByLength(thePolyLine.ToPoint, theFromPoint,
                                                                         theTangentpoint, isCCW, theFromCurvature, theToCurvature, theSpiralLength,
                                                                         out dCurvature, out dSplitLength, out dSplitAngle, out pExitTangentLine);
                    ExitTangent = pExitTangentLine.Angle; //returns polar azimuth in radians
                }

                #region tests

                //TEST +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                //IAngularConverter pAngConv = new AngularConverterClass();
                //double dCurvatureTEST = 0;
                //double dSplitLengthTEST = 0;
                //double dSplitAngleTEST = 0;
                //double ExitTangentTEST = 0;
                //ILine pExitTangentLineTEST = null;

                ////IPoint theFromPoint = new PointClass();
                ////theFromPoint.PutCoords(2356762.676, 1919302.7);
                ////theFromPoint.SpatialReference = ArcMap.Document.ActiveView.FocusMap.SpatialReference;

                ////IPoint theTangentpoint = new PointClass();
                ////theTangentpoint.PutCoords(2356409.122, 1918949.146);
                ////theTangentpoint.SpatialReference = ArcMap.Document.ActiveView.FocusMap.SpatialReference;

                //IPoint TESTPOINT1 = new PointClass();
                //TESTPOINT1.PutCoords(2356868.410, 1918327.316);
                //TESTPOINT1.SpatialReference = ArcMap.Document.ActiveView.FocusMap.SpatialReference;

                //IPoint TESTPOINT2 = new PointClass();
                //TESTPOINT2.PutCoords(2356876.899, 1918316.005);
                //TESTPOINT2.SpatialReference = ArcMap.Document.ActiveView.FocusMap.SpatialReference;

                //IPoint TESTPOINT3 = new PointClass();
                //TESTPOINT3.PutCoords(2356884.312, 1918317.906);
                //TESTPOINT3.SpatialReference = ArcMap.Document.ActiveView.FocusMap.SpatialReference;

                //IPoint TESTPOINT4 = new PointClass();
                //TESTPOINT4.PutCoords(2356872.308, 1918333.903);
                //TESTPOINT4.SpatialReference = ArcMap.Document.ActiveView.FocusMap.SpatialReference;


                //IPoint TESTPOINTA_Centroid = new PointClass();
                //TESTPOINTA_Centroid.PutCoords(2356633.395, 1918788.139);
                //TESTPOINTA_Centroid.SpatialReference = ArcMap.Document.ActiveView.FocusMap.SpatialReference;

                //IPoint TESTPOINTB_Centroid_OnCurve = new PointClass();
                //TESTPOINTB_Centroid_OnCurve.PutCoords(2356633.396, 1918788.358);
                //TESTPOINTB_Centroid_OnCurve.SpatialReference = ArcMap.Document.ActiveView.FocusMap.SpatialReference;

                //IPoint TESTPOINTC_OutsideOffsetTransferredToCurve = new PointClass();
                //TESTPOINTC_OutsideOffsetTransferredToCurve.PutCoords(2356511.754, 1919017.119);
                //TESTPOINTC_OutsideOffsetTransferredToCurve.SpatialReference = ArcMap.Document.ActiveView.FocusMap.SpatialReference;

                //IPoint TESTPOINTD_OutsideOffsetPoint = new PointClass();
                //TESTPOINTD_OutsideOffsetPoint.PutCoords(2355963.185,1919377.363);
                //TESTPOINTD_OutsideOffsetPoint.SpatialReference = ArcMap.Document.ActiveView.FocusMap.SpatialReference;


                //IPoint ComputedEndPOINT = new PointClass();
                //ComputedEndPOINT.PutCoords(2356878.31, 1918325.904);
                //ComputedEndPOINT.SpatialReference = ArcMap.Document.ActiveView.FocusMap.SpatialReference;

                //string sReport = "";

                //if (thePolyLine != null)
                //{

                //  TheSpiralConstruction.ConstructSplitClothoidByLength(thePolyLine.ToPoint, theFromPoint,
                //  theTangentpoint, isCCW, theFromCurvature, theToCurvature, theSpiralLength,
                //  out dCurvatureTEST, out dSplitLengthTEST, out dSplitAngleTEST, out pExitTangentLineTEST);
                //  ExitTangentTEST = pExitTangentLineTEST.Angle; //returns polar azimuth in radians

                //  pAngConv.SetAngle(ExitTangentTEST, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians);
                //  string sTangentBearing = pAngConv.GetString(esriDirectionType.esriDTQuadrantBearing, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);
                //  pAngConv.SetAngle(dSplitAngleTEST, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians); //returns polar azimuth in radians
                //  string sSplitCentralAngle = pAngConv.GetString(esriDirectionType.esriDTPolar, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);
                //  sReport += ("To Point " +Environment.NewLine + "------------------" + Environment.NewLine +
                //    "Curvature at To point          : " + dCurvatureTEST.ToString("0.00000") + Environment.NewLine +
                //    "Radius at To point          : " + (1/dCurvatureTEST).ToString("0.00000") + Environment.NewLine +
                //    "Length along curve at To point : " + dSplitLengthTEST.ToString("0.00") + Environment.NewLine +
                //    "Central angle  at To  point     : " + sSplitCentralAngle + Environment.NewLine +
                //    "Tangent bearing at To point    : " + sTangentBearing + Environment.NewLine
                //    );



                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //        TheSpiralConstruction.ConstructSplitClothoidByLength(TESTPOINT1, theFromPoint,
                //theTangentpoint, isCCW, theFromCurvature, theToCurvature, theSpiralLength,
                //out dCurvatureTEST, out dSplitLengthTEST, out dSplitAngleTEST, out pExitTangentLineTEST);
                //        ExitTangentTEST = pExitTangentLineTEST.Angle; //returns polar azimuth in radians

                //        pAngConv.SetAngle(ExitTangentTEST, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians);
                //        sTangentBearing = pAngConv.GetString(esriDirectionType.esriDTQuadrantBearing, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);
                //        pAngConv.SetAngle(dSplitAngleTEST, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians); //returns polar azimuth in radians
                //        sSplitCentralAngle = pAngConv.GetString(esriDirectionType.esriDTPolar, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);
                //        sReport += ("TESTPOINT1" +Environment.NewLine + "---" + Environment.NewLine +
                //          "Curvature at query point          : " + dCurvatureTEST.ToString("0.00000") + Environment.NewLine +
                //          "Length along curve at query point : " + dSplitLengthTEST.ToString("0.00") + Environment.NewLine +
                //          "Central angle  at query point     : " + sSplitCentralAngle + Environment.NewLine +
                //          "Tangent bearing at query point    : " + sTangentBearing + Environment.NewLine
                //          );


                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //        TheSpiralConstruction.ConstructSplitClothoidByLength(TESTPOINT2, theFromPoint,
                //theTangentpoint, isCCW, theFromCurvature, theToCurvature, theSpiralLength,
                //out dCurvatureTEST, out dSplitLengthTEST, out dSplitAngleTEST, out pExitTangentLineTEST);
                //        ExitTangentTEST = pExitTangentLineTEST.Angle; //returns polar azimuth in radians

                //        pAngConv.SetAngle(ExitTangentTEST, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians);
                //        sTangentBearing = pAngConv.GetString(esriDirectionType.esriDTQuadrantBearing, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);
                //        pAngConv.SetAngle(dSplitAngleTEST, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians); //returns polar azimuth in radians
                //        sSplitCentralAngle = pAngConv.GetString(esriDirectionType.esriDTPolar, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);
                //        sReport += ("TESTPOINT2" +Environment.NewLine + "---" + Environment.NewLine +
                //          "Curvature at query point          : " + dCurvatureTEST.ToString("0.00000") + Environment.NewLine +
                //          "Length along curve at query point : " + dSplitLengthTEST.ToString("0.00") + Environment.NewLine +
                //          "Central angle  at query point     : " + sSplitCentralAngle + Environment.NewLine +
                //          "Tangent bearing at query point    : " + sTangentBearing + Environment.NewLine
                //          );


                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //        TheSpiralConstruction.ConstructSplitClothoidByLength(TESTPOINT3, theFromPoint,
                //theTangentpoint, isCCW, theFromCurvature, theToCurvature, theSpiralLength,
                //out dCurvatureTEST, out dSplitLengthTEST, out dSplitAngleTEST, out pExitTangentLineTEST);
                //        ExitTangentTEST = pExitTangentLineTEST.Angle; //returns polar azimuth in radians

                //        pAngConv.SetAngle(ExitTangentTEST, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians);
                //        sTangentBearing = pAngConv.GetString(esriDirectionType.esriDTQuadrantBearing, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);
                //        pAngConv.SetAngle(dSplitAngleTEST, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians); //returns polar azimuth in radians
                //        sSplitCentralAngle = pAngConv.GetString(esriDirectionType.esriDTPolar, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);
                //        sReport += ("TESTPOINT3" +Environment.NewLine + "---" + Environment.NewLine +
                //          "Curvature at query point          : " + dCurvatureTEST.ToString("0.00000") + Environment.NewLine +
                //          "Length along curve at query point : " + dSplitLengthTEST.ToString("0.00") + Environment.NewLine +
                //          "Central angle  at query point     : " + sSplitCentralAngle + Environment.NewLine +
                //          "Tangent bearing at query point    : " + sTangentBearing + Environment.NewLine
                //          );


                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //TheSpiralConstruction.ConstructSplitClothoidByLength(TESTPOINT4, theFromPoint,
                //  theTangentpoint, isCCW, theFromCurvature, theToCurvature, theSpiralLength,
                //  out dCurvatureTEST, out dSplitLengthTEST, out dSplitAngleTEST, out pExitTangentLineTEST);
                //ExitTangentTEST = pExitTangentLineTEST.Angle; //returns polar azimuth in radians

                //pAngConv.SetAngle(ExitTangentTEST, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians);
                //sTangentBearing = pAngConv.GetString(esriDirectionType.esriDTQuadrantBearing, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);
                //pAngConv.SetAngle(dSplitAngleTEST, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians); //returns polar azimuth in radians
                //sSplitCentralAngle = pAngConv.GetString(esriDirectionType.esriDTPolar, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);
                //sReport += ("TESTPOINT4" +Environment.NewLine + "---" + Environment.NewLine +
                //  "Curvature at query point          : " + dCurvatureTEST.ToString("0.00000") + Environment.NewLine +
                //  "Length along curve at query point : " + dSplitLengthTEST.ToString("0.00") + Environment.NewLine +
                //  "Central angle  at query point     : " + sSplitCentralAngle + Environment.NewLine +
                //  "Tangent bearing at query point    : " + sTangentBearing + Environment.NewLine
                //  );


                /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //TheSpiralConstruction.ConstructSplitClothoidByLength(TESTPOINTA_Centroid, theFromPoint,
                //  theTangentpoint, isCCW, theFromCurvature, theToCurvature, theSpiralLength,
                //  out dCurvatureTEST, out dSplitLengthTEST, out dSplitAngleTEST, out pExitTangentLineTEST);
                //ExitTangentTEST = pExitTangentLineTEST.Angle; //returns polar azimuth in radians

                //pAngConv.SetAngle(ExitTangentTEST, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians);
                //sTangentBearing = pAngConv.GetString(esriDirectionType.esriDTQuadrantBearing, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);
                //pAngConv.SetAngle(dSplitAngleTEST, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians); //returns polar azimuth in radians
                //sSplitCentralAngle = pAngConv.GetString(esriDirectionType.esriDTPolar, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);
                //sReport += ("A " +Environment.NewLine + "------------------" + Environment.NewLine +
                //  "Curvature; query point A         : " + dCurvatureTEST.ToString("0.00000") + Environment.NewLine +
                //  "Radius; query point A         : " + (1/dCurvatureTEST).ToString("0.00000") + Environment.NewLine +
                //  "Length along curve; query point A: " + dSplitLengthTEST.ToString("0.00") + Environment.NewLine +
                //  "Central angle; query point A    : " + sSplitCentralAngle + Environment.NewLine +
                //  "Tangent bearing; query point A   : " + sTangentBearing + Environment.NewLine
                //  );


                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //TheSpiralConstruction.ConstructSplitClothoidByLength(TESTPOINTB_Centroid_OnCurve, theFromPoint,
                //  theTangentpoint, isCCW, theFromCurvature, theToCurvature, theSpiralLength,
                //  out dCurvatureTEST, out dSplitLengthTEST, out dSplitAngleTEST, out pExitTangentLineTEST);
                //ExitTangentTEST = pExitTangentLineTEST.Angle; //returns polar azimuth in radians

                //pAngConv.SetAngle(ExitTangentTEST, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians);
                //sTangentBearing = pAngConv.GetString(esriDirectionType.esriDTQuadrantBearing, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);
                //pAngConv.SetAngle(dSplitAngleTEST, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians); //returns polar azimuth in radians
                //sSplitCentralAngle = pAngConv.GetString(esriDirectionType.esriDTPolar, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);
                //sReport += ("B " +Environment.NewLine + "---" + Environment.NewLine +
                //  "Curvature; query point B         : " + dCurvatureTEST.ToString("0.00000") + Environment.NewLine +
                //  "Radius; query point B         : " + (1/dCurvatureTEST).ToString("0.00000") + Environment.NewLine +
                //  "Length along curve; query point B : " + dSplitLengthTEST.ToString("0.00") + Environment.NewLine +
                //  "Central angle; query point B    : " + sSplitCentralAngle + Environment.NewLine +
                //  "Tangent bearing; query point B   : " + sTangentBearing + Environment.NewLine
                //  );


                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //TheSpiralConstruction.ConstructSplitClothoidByLength(TESTPOINTC_OutsideOffsetTransferredToCurve, theFromPoint,
                //  theTangentpoint, isCCW, theFromCurvature, theToCurvature, theSpiralLength,
                //  out dCurvatureTEST, out dSplitLengthTEST, out dSplitAngleTEST, out pExitTangentLineTEST);
                //ExitTangentTEST = pExitTangentLineTEST.Angle; //returns polar azimuth in radians

                //pAngConv.SetAngle(ExitTangentTEST, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians);
                //sTangentBearing = pAngConv.GetString(esriDirectionType.esriDTQuadrantBearing, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);
                //pAngConv.SetAngle(dSplitAngleTEST, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians); //returns polar azimuth in radians
                //sSplitCentralAngle = pAngConv.GetString(esriDirectionType.esriDTPolar, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);
                //sReport += ("C " +Environment.NewLine + "---" + Environment.NewLine +
                //  "Curvature; query point C         : " + dCurvatureTEST.ToString("0.00000") + Environment.NewLine +
                //  "Radius; query point C         : " + (1/dCurvatureTEST).ToString("0.00000") + Environment.NewLine +
                //  "Length along curve; query point C: " + dSplitLengthTEST.ToString("0.00") + Environment.NewLine +
                //  "Central angle ; query point C    : " + sSplitCentralAngle + Environment.NewLine +
                //  "Tangent bearing; query point C   : " + sTangentBearing + Environment.NewLine
                //  );


                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //  TheSpiralConstruction.ConstructSplitClothoidByLength(TESTPOINTD_OutsideOffsetPoint, theFromPoint,
                //    theTangentpoint, isCCW, theFromCurvature, theToCurvature, theSpiralLength,
                //    out dCurvatureTEST, out dSplitLengthTEST, out dSplitAngleTEST, out pExitTangentLineTEST);
                //  ExitTangentTEST = pExitTangentLineTEST.Angle; //returns polar azimuth in radians

                //  pAngConv.SetAngle(ExitTangentTEST, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians);
                //  sTangentBearing = pAngConv.GetString(esriDirectionType.esriDTQuadrantBearing, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);
                //  pAngConv.SetAngle(dSplitAngleTEST, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians); //returns polar azimuth in radians
                //  sSplitCentralAngle = pAngConv.GetString(esriDirectionType.esriDTPolar, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);
                //  sReport += ("D " +Environment.NewLine + "---------------" + Environment.NewLine +
                //    "Curvature; query point D         : " + dCurvatureTEST.ToString("0.00000") + Environment.NewLine +
                //    "Radius; query point D         : " + (1/dCurvatureTEST).ToString("0.00000") + Environment.NewLine +
                //    "Length along curve; query point D: " + dSplitLengthTEST.ToString("0.00") + Environment.NewLine +
                //    "Central angle; query point D    : " + sSplitCentralAngle + Environment.NewLine +
                //    "Tangent bearing; query point D   : " + sTangentBearing + Environment.NewLine
                //    );

                //  MessageBox.Show(sReport, "Query Point Results");

                //}

                //END TEST ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                #endregion

                return(thePolyLine);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return(null);
            }
        }