public static void CalculateRandomTargetLine(LineModel directionLine1, LineModel directionLine2, LineModel directionLine3, ref LineModel randomTargetLine, ref TextBox randomTargetLineText, ref TextBox targetLineLengthDiffText, ref TextBox randomTargetLineMethodText)
        {
            if (directionLine1 == null || directionLine2 == null || directionLine3 == null)
            {
                return;
            }

            var randomTaretLineByMath    = CoordinateSystemOperation.CalculateRandomTargetLineByMath(directionLine1, directionLine2, directionLine3);
            var randomTargetLineByRotate = CoordinateSystemOperation.CalculateRandomTargetLineByRotate(directionLine1, directionLine2, directionLine3);

            if (randomTargetLineByRotate == null)
            {
                MessageBox.Show("calculate parallel route failed.");
                return;
            }

            var rotateLineDiff = CalculateRandomTargetLineLengthDiff(directionLine1, directionLine2, directionLine3, randomTargetLineByRotate);
            var mathLineDiff   = CalculateRandomTargetLineLengthDiff(directionLine1, directionLine2, directionLine3, randomTaretLineByMath);

            if (rotateLineDiff < mathLineDiff)
            {
                randomTargetLine = randomTargetLineByRotate;
                randomTargetLineMethodText.Text = "ROTATE";
                targetLineLengthDiffText.Text   = rotateLineDiff.ToString();
            }
            else
            {
                randomTargetLine = randomTaretLineByMath;
                randomTargetLineMethodText.Text = "CALCULATE";
                targetLineLengthDiffText.Text   = mathLineDiff.ToString();
            }

            randomTargetLineText.Text = randomTargetLine.ToString();
        }
        public static void CalculateActualTargetLine(LineModel randomTargetLine, LineModel estimatedDirectionLine, LineModel directionLine1, LineModel directionLine2, LineModel directionLine3, LineModel directionLine4, TextBox observePos1TimeDiffText, ref LineModel actualTargetLine, ref TextBox actualTargetLineText, ref PointModel targetConfirmedPoint, ref DateTime targetConfirmedPointDate, ref TextBox targetSpeedText)
        {
            if (randomTargetLine == null || estimatedDirectionLine == null || directionLine4 == null)
            {
                return;
            }

            targetConfirmedPoint      = CoordinateSystemOperation.CalculatePointByTwoLines(estimatedDirectionLine, directionLine4);
            targetConfirmedPointDate  = DateTime.Now;
            actualTargetLine          = CoordinateSystemOperation.CalculateLineFromSlopeAndPoint(randomTargetLine.a, targetConfirmedPoint, randomTargetLine.lineDirection);
            actualTargetLineText.Text = actualTargetLine.ToString();

            if (string.IsNullOrEmpty(observePos1TimeDiffText.Text) || directionLine1 == null || directionLine2 == null || directionLine3 == null)
            {
                return;
            }

            double time;

            try
            {
                time = Convert.ToDouble(observePos1TimeDiffText.Text);
            }
            catch
            {
                MessageBox.Show("invalid number: " + observePos1TimeDiffText.Text);
                return;
            }

            var intercept1   = CoordinateSystemOperation.CalculatePointByTwoLines(actualTargetLine, directionLine1);
            var intercept2   = CoordinateSystemOperation.CalculatePointByTwoLines(actualTargetLine, directionLine2);
            var intercept3   = CoordinateSystemOperation.CalculatePointByTwoLines(actualTargetLine, directionLine3);
            var length       = (CoordinateSystemOperation.CalculateLengthBetweenPoints(intercept1, intercept2) + CoordinateSystemOperation.CalculateLengthBetweenPoints(intercept2, intercept3)) / 2.00;
            var speedByMeter = length / time;
            var speedByKnot  = speedByMeter * 1.94;

            targetSpeedText.Text = Math.Round(speedByKnot, 2).ToString();

            var actualDirectionLine = CoordinateSystemOperation.CalculateLineFromTwoPoint(intercept1, intercept2);

            actualTargetLine.lineDirection = actualDirectionLine.lineDirection;
        }
        public static void CalculateDirectionLine(TextBox subHeadingText, TextBox directionText, TextBox observePos1PositionText, ref LineModel directionLine, ref TextBox directionLineText, bool isObservePos1DirectionLine = true)
        {
            if (string.IsNullOrEmpty(directionText.Text) || string.IsNullOrEmpty(subHeadingText.Text))
            {
                return;
            }

            double direction, subHeading;

            try
            {
                direction  = Convert.ToDouble(directionText.Text);
                subHeading = Convert.ToDouble(subHeadingText.Text);
            }
            catch
            {
                MessageBox.Show("invalid number: " + directionText.Text + ", " + subHeadingText.Text);
                return;
            }

            direction = DirectionOperation.CalculateSubActualDirection(subHeading, direction);

            PointModel observePos = new PointModel(0, 0);

            if (isObservePos1DirectionLine && !string.IsNullOrEmpty(observePos1PositionText.Text))
            {
                observePos = PointModel.Parse(observePos1PositionText.Text);

                if (observePos == null)
                {
                    return;
                }
            }

            directionLine          = CoordinateSystemOperation.CalculateLineFromPointAndDirection(observePos, direction);
            directionLineText.Text = directionLine.ToString();
        }
        public static void CalculateEstimatedDirectionLine(LineModel directionLine1, LineModel directionLine2, LineModel directionLine3, LineModel randomTargetLine, TextBox observePos1Text, TextBox observePos1TimeDiffText, TextBox observePos2TimeDiffText, ref LineModel estimatedDirectionLine, ref TextBox estimatedDirectionLineText, ref TextBox targetHeadingText)
        {
            if (directionLine1 == null || directionLine2 == null || directionLine3 == null || randomTargetLine == null)
            {
                return;
            }

            double pos2LengthRatio = 1;

            if (!string.IsNullOrEmpty(observePos1TimeDiffText.Text) && !string.IsNullOrEmpty(observePos2TimeDiffText.Text))
            {
                try
                {
                    double pos1TimeDiff = Convert.ToDouble(observePos1TimeDiffText.Text);
                    double pos2TimeDiff = Convert.ToDouble(observePos2TimeDiffText.Text);
                    pos2LengthRatio = pos2TimeDiff / pos1TimeDiff;
                }
                catch
                {  }
            }

            var intercept1 = CoordinateSystemOperation.CalculatePointByTwoLines(directionLine1, randomTargetLine);
            var intercept2 = CoordinateSystemOperation.CalculatePointByTwoLines(directionLine2, randomTargetLine);
            var intercept3 = CoordinateSystemOperation.CalculatePointByTwoLines(directionLine3, randomTargetLine);

            var length1 = CoordinateSystemOperation.CalculateLengthBetweenPoints(intercept1, intercept2);
            var length2 = CoordinateSystemOperation.CalculateLengthBetweenPoints(intercept2, intercept3);
            var length  = (length1 + length2) / 2;

            length = length * pos2LengthRatio;

            LineDirection direction;

            if (intercept2.x > intercept1.x)
            {
                direction = LineDirection.LEFT_TO_RIGHT;
            }
            else
            {
                direction = LineDirection.RIGHT_TO_LEFT;
            }

            PointModel observePos = new PointModel(0, 0);

            if (!string.IsNullOrEmpty(observePos1Text.Text))
            {
                observePos = PointModel.Parse(observePos1Text.Text);
                if (observePos == null)
                {
                    return;
                }
            }

            var estimatedPoint = CoordinateSystemOperation.CalculatePointByLineAndLength(randomTargetLine, intercept3, length, direction);

            estimatedDirectionLine          = CoordinateSystemOperation.CalculateLineFromTwoPoint(observePos, estimatedPoint);
            estimatedDirectionLineText.Text = estimatedDirectionLine.ToString();

            var headingLine = CoordinateSystemOperation.CalculateLineFromTwoPoint(intercept1, intercept2);
            var heading     = CoordinateSystemOperation.CalculateDirectionFromLine(headingLine);

            targetHeadingText.Text = Math.Round(heading, 2).ToString();
        }