/// <summary>
        /// 給定 3 點,找圓心座標
        /// </summary>
        /// <param name="pA"></param>
        /// <param name="pB"></param>
        /// <param name="pC"></param>
        /// <param name="centerRow"></param>
        /// <param name="centerCol"></param>
        public static void CalculateCircleCenter(GeoPoint pA, GeoPoint pB, GeoPoint pC
            , out double centerRow, out double centerCol)
        {
            centerRow = centerCol = -1;
            if (pA != null && pB != null && pC != null)
            {
                var a1 = pA.Col;
                var b1 = pA.Row;
                var a2 = pB.Col;
                var b2 = pB.Row;
                var a3 = pC.Col;
                var b3 = pC.Row;
                var a1s = Math.Pow(a1, 2);
                var a2s = Math.Pow(a2, 2);
                var a3s = Math.Pow(a3, 2);
                var b1s = Math.Pow(b1, 2);
                var b2s = Math.Pow(b2, 2);
                var b3s = Math.Pow(b3, 2);

                centerCol = (a1s * b2
                        - a1s * b3
                        + b1 * b3s
                        - b1 * a2s
                        + b3 * a2s
                        - b3s * b2
                        + b3 * b2s
                        - b1 * b2s
                        + b1 * a3s
                        - b1s * b3
                        - a3s * b2
                        + b1s * b2) /
                        (2 * (a1 * b2 + a3 * b1 - a3 * b2 - a1 * b3 - a2 * b1 + a2 * b3));

                centerRow = -0.5 * (-1 * a1 * a2s
               + a2 * b1s
               - a1 * b2s
               - a3 * a1s
               - a2 * b3s
               - a3 * b1s
               + a3 * a2s
               + a1 * b3s
               + a3 * b2s
               + a1 * a3s
               - a2 * a3s
               + a2 * a1s) /
               (a1 * b2 + a3 * b1 - a3 * b2 - a1 * b3 - a2 * b1 + a2 * b3);
            }
        }
 /// <summary>
 /// 給定 3 點,找圓心座標及半徑
 /// </summary>
 /// <param name="pA"></param>
 /// <param name="pB"></param>
 /// <param name="pC"></param>
 /// <param name="centerRow"></param>
 /// <param name="centerCol"></param>
 /// <param name="radius"></param>
 public static void CalculateCircleCenter(GeoPoint pA, GeoPoint pB, GeoPoint pC
     , out double centerRow, out double centerCol, out double radius)
 {
     radius = -1;
     CalculateCircleCenter(pA, pB, pC, out centerRow, out centerCol);
     if (pA != null && pA.Row > 0 && pA.Col > 0 && centerRow > 0 && centerCol > 0)
     {
         radius = CalculateDistance(centerRow, centerCol, pA.Row, pA.Col);
     }
 }
Example #3
0
        public bool WaitForClickPoints(double x, double y)
        {
            if (_clickedPointsPositionList.Count < _clickPoints)
            {
                _clickedPointsPositionList.Add(new PositionModel() { ColBegin = x, RowBegin = y });
            }
            _initPointsDone = _clickedPointsPositionList.Count == _clickPoints;
            if (_initPointsDone)
            {
                //3 點求圓
                var rows = _clickedPointsPositionList.Select(p => p.RowBegin).ToArray();
                var cols = _clickedPointsPositionList.Select(p => p.ColBegin).ToArray();
                GeoOperatorSet.CalculateCircleCenter(rows, cols, out midR, out midC, out radius);

                //檢查 and notify
                _success = (midR > 0 && midC > 0 && radius > 0);
                if (_success)
                {
                    _FirstPoint = new GeoPoint() { Row = rows[0], Col = cols[0] };
                    _SecondPoint = new GeoPoint() { Row = rows[1], Col = cols[1] };
                    _EndPoint = new GeoPoint() { Row = rows[2], Col = cols[2] };

                    //
                    sizeR = midR;
                    sizeC = midC - radius;

                    //toDo, 計算startPhi, extentPhi
                    // 角度為正,表示在圓心的上方,反之在下方
                    // 角度越大,表示越接近左上角,視為起始點
                    // 角度越小,視為終點
                    var agOne = HMisc.AngleLx(midR, midC, _FirstPoint.Row, _FirstPoint.Col);
                    var agTwo = HMisc.AngleLx(midR, midC, _SecondPoint.Row, _SecondPoint.Col);
                    var agThree = HMisc.AngleLx(midR, midC, _EndPoint.Row, _EndPoint.Col);
                    Dictionary<string, double> agDict = new Dictionary<string, double>() { };
                    agDict.Add("1", agOne);
                    agDict.Add("2", agTwo);
                    agDict.Add("3", agThree);

                    //逆排序,再取奇數, 即為 StartPhi, EndPhi
                    var angles = agDict.OrderByDescending(p => p.Value)
                                        .Where((p, idx) => idx % 2 == 0)
                                        .Select(p => p.Value).ToArray();
                    _startPhi = angles[0];
                    var endPhi = angles[1];

                    //計算延伸長度
                    /*
                     * 起始點在第一,二象限,則
                     */
                    _extentPhi = (_startPhi < 0) ? Math.Abs(_startPhi) - Math.Abs(endPhi)
                                                : endPhi - _startPhi;
                    _pointOrder = "negative";//clockwise 畫弧

                    determineArcHandles();
                    updateArrowHandle();
                }
            }
            return _initPointsDone;
        }