/// <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); } }
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; }