/// <summary>>開始点、終了点、弧の半径、描画方向,大小弧によって返回円の中心点を取得</summary> /// <param name="startPoint">開始点</param> /// <param name="endPoint">終了点</param> /// <param name="radius">半径</param> /// <param name="sweepDirection">弧が描画される方向</param> /// <param name="isLargeArc">True:大弧,False:小弧 </param> /// <returns>円の中心点</returns> public static Point GetRoundCenter(Point startPoint, Point endPoint, double radius, SweepDirection sweepDirection, bool isLargeArc) { // 開始と終了点が同じの場合 if (startPoint == endPoint) { throw new BaseException(Consts.ERROR_JOBEDIT_007); } //開始点と終了点の長さ(※現在の実装方法が不可能) double width = Math.Sqrt((startPoint.Y - endPoint.Y) * (startPoint.Y - endPoint.Y) + (startPoint.X - endPoint.X) * (startPoint.X - endPoint.X)); if (width > radius * 2) { throw new RadiusException(""); } //交差点 Point crossingPoint = new Point((startPoint.X + endPoint.X) / 2, (startPoint.Y + endPoint.Y) / 2); //開始点と終了点の傾度 double k1 = (startPoint.Y - endPoint.Y) / (startPoint.X - endPoint.X); //交差点と円の中心の傾度 double k2; //交差点と円の中心の長さ double distance; distance = Math.Sqrt(radius * radius - (width * width) / 4); //円の中心 Point roundCenterLeft = new Point(); Point roundCenterRight = new Point(); // 傾度が無限大の場合(開始点と終了点のY座標が同じ) if (double.IsInfinity(k1)) { roundCenterLeft = new Point(crossingPoint.X + distance, crossingPoint.Y); roundCenterRight = new Point(crossingPoint.X - distance, crossingPoint.Y); } // 傾度が0の場合(開始点と終了点のX座標が同じ) else if (k1 == 0) { roundCenterLeft = new Point(crossingPoint.X, crossingPoint.Y + distance); roundCenterRight = new Point(crossingPoint.X, crossingPoint.Y - distance); } // その他の場合 else { k2 = (-1) / k1; double xOffset = distance / (Math.Sqrt(1 + k2 * k2)); double xTemp, yTemp; #region 一番目の円の中心点 xTemp = crossingPoint.X + xOffset; yTemp = k2 * (xTemp - crossingPoint.X) + crossingPoint.Y; roundCenterLeft = new Point(Math.Round(xTemp, 4), Math.Round(yTemp, 4)); #endregion #region ニ番目の円の中心点 xTemp = crossingPoint.X - xOffset; yTemp = k2 * (xTemp - crossingPoint.X) + crossingPoint.Y; roundCenterRight = new Point(Math.Round(xTemp, 4), Math.Round(yTemp, 4)); #endregion } if (-1 == MathExtension.GetPointLeftOrRight(startPoint, endPoint, roundCenterLeft)) { Point pointTemp = roundCenterLeft; roundCenterLeft = roundCenterRight; roundCenterRight = pointTemp; } //大弧 if (isLargeArc) { //時計回り (正の角) 、 右の円の中心を取得 if (sweepDirection == SweepDirection.Clockwise) { return(roundCenterRight); } // 反時計回り (負の角) 、 左の円の中心を取得 else { return(roundCenterLeft); } } //小弧 else { //時計回り (正の角) 、 左の円の中心を取得 if (sweepDirection == SweepDirection.Clockwise) { return(roundCenterLeft); } // 反時計回り (負の角) 、 右の円の中心を取得 else { return(roundCenterRight); } } }
/// <summary>位置をセット</summary> public void SetPosition() { // 弧 this.lineElement.Point = this.EndPoint; this.LinePathFigureElement.StartPoint = this.StartPoint; this.lineElement.IsLargeArc = this.IsLargeArc; this.lineElement.SweepDirection = this.LineSweepDirection; this.lineElement.Size = new Size(this.Radius, this.Radius); // 矢印 _roundCenter = new Point(); double k1; //円の中心点を取得 try { _roundCenter = MathExtension.GetRoundCenter(this.StartPoint, this.EndPoint, this.Radius, this.LineSweepDirection, this.IsLargeArc); //円の中心点と矢印点の傾斜度 k1 = (_roundCenter.Y - this.EndPoint.Y) / (_roundCenter.X - this.EndPoint.X); } catch (Exception ex) { if (ex is RadiusException) { k1 = (-1) * (this.StartPoint.X - this.EndPoint.X) / (this.StartPoint.Y - this.EndPoint.Y); this.lineElement.Size = new Size(0, 1); } else { return; } } Point centerPoint1, centerPoint2, endPoint11, endPoint12, endPoint21, endPoint22; //接線の傾斜度 double k2 = 0; // Y軸方向 if (double.IsInfinity(k1)) { //開始点と終了点の中点 this._CenterPoint.X = (this.StartPoint.X + this.EndPoint.X) / 2; this._CenterPoint.Y = (this.StartPoint.Y + this.EndPoint.Y) / 2; //Y軸方向の直線 if (this.IsBeeline) { if (this.StartPoint.X < this.EndPoint.X) { this.arrowStartElement.StartPoint = new Point(this.EndPoint.X - this.ArrowSize.Height, this.EndPoint.Y - this.ArrowSize.Width); this.arrowElement.Points.Clear(); this.arrowElement.Points.Add(this.EndPoint); this.arrowElement.Points.Add(new Point(this.EndPoint.X - this.ArrowSize.Height, this.EndPoint.Y + this.ArrowSize.Width)); } else { this.arrowStartElement.StartPoint = new Point(this.EndPoint.X + this.ArrowSize.Height, this.EndPoint.Y - this.ArrowSize.Width); this.arrowElement.Points.Clear(); this.arrowElement.Points.Add(this.EndPoint); this.arrowElement.Points.Add(new Point(this.EndPoint.X + this.ArrowSize.Height, this.EndPoint.Y + this.ArrowSize.Width)); } } } // X軸方向 else if (Math.Round(k1, 4) == 0) { //開始点と終了点の中点 this._CenterPoint.X = (this.StartPoint.X + this.EndPoint.X) / 2; this._CenterPoint.Y = (this.StartPoint.Y + this.EndPoint.Y) / 2; //X軸方向の直线 if (this.IsBeeline) { if (this.StartPoint.Y < this.EndPoint.Y) { this.arrowStartElement.StartPoint = new Point(this.EndPoint.X - this.ArrowSize.Width, this.EndPoint.Y - this.ArrowSize.Height); this.arrowElement.Points.Clear(); this.arrowElement.Points.Add(this.EndPoint); this.arrowElement.Points.Add(new Point(this.EndPoint.X + this.ArrowSize.Width, this.EndPoint.Y - this.ArrowSize.Height)); } else { this.arrowStartElement.StartPoint = new Point(this.EndPoint.X - this.ArrowSize.Width, this.EndPoint.Y + this.ArrowSize.Height); this.arrowElement.Points.Clear(); this.arrowElement.Points.Add(this.EndPoint); this.arrowElement.Points.Add(new Point(this.EndPoint.X + this.ArrowSize.Width, this.EndPoint.Y + this.ArrowSize.Height)); } } } else { k2 = (-1) / k1; double xOffset = this.ArrowSize.Height / (Math.Sqrt(1 + k2 * k2)); double xTemp, yTemp; // 一番目の点 xTemp = this.EndPoint.X + xOffset; yTemp = k2 * (xTemp - this.EndPoint.X) + this.EndPoint.Y; centerPoint1 = new Point(Math.Round(xTemp, 4), Math.Round(yTemp, 4)); // ニ番目の点 xTemp = this.EndPoint.X - xOffset; yTemp = k2 * (xTemp - this.EndPoint.X) + this.EndPoint.Y; centerPoint2 = new Point(Math.Round(xTemp, 4), Math.Round(yTemp, 4)); k2 = k1; xOffset = this.ArrowSize.Width / (Math.Sqrt(1 + k2 * k2)); // 矢印の点 xTemp = centerPoint1.X + xOffset; yTemp = k2 * (xTemp - centerPoint1.X) + centerPoint1.Y; endPoint11 = new Point(Math.Round(xTemp, 4), Math.Round(yTemp, 4)); xTemp = centerPoint1.X - xOffset; yTemp = k2 * (xTemp - centerPoint1.X) + centerPoint1.Y; endPoint12 = new Point(Math.Round(xTemp, 4), Math.Round(yTemp, 4)); // 矢印の点 xTemp = centerPoint2.X + xOffset; yTemp = k2 * (xTemp - centerPoint2.X) + centerPoint2.Y; endPoint21 = new Point(Math.Round(xTemp, 4), Math.Round(yTemp, 4)); xTemp = centerPoint2.X - xOffset; yTemp = k2 * (xTemp - centerPoint2.X) + centerPoint2.Y; endPoint22 = new Point(Math.Round(xTemp, 4), Math.Round(yTemp, 4)); //小弧 if (!this.IsLargeArc) { #region 小弧 //直線の場合 if (this.IsBeeline) { double d1 = (endPoint11.X - this.StartPoint.X) * (endPoint11.X - this.StartPoint.X) + (endPoint11.Y - this.StartPoint.Y) * (endPoint11.Y - this.StartPoint.Y); double d2 = (endPoint21.X - this.StartPoint.X) * (endPoint21.X - this.StartPoint.X) + (endPoint21.Y - this.StartPoint.Y) * (endPoint21.Y - this.StartPoint.Y); if (d1 < d2) { this.arrowStartElement.StartPoint = endPoint11; this.arrowElement.Points.Clear(); this.arrowElement.Points.Add(this.EndPoint); this.arrowElement.Points.Add(endPoint12); } else { this.arrowStartElement.StartPoint = endPoint21; this.arrowElement.Points.Clear(); this.arrowElement.Points.Add(this.EndPoint); this.arrowElement.Points.Add(endPoint22); } } else { //点の位置を判定 if (MathExtension.GetPointLeftOrRight(_roundCenter, this.EndPoint, this.StartPoint) == MathExtension.GetPointLeftOrRight(_roundCenter, this.EndPoint, centerPoint1)) { this.arrowStartElement.StartPoint = endPoint11; this.arrowElement.Points.Clear(); this.arrowElement.Points.Add(this.EndPoint); this.arrowElement.Points.Add(endPoint12); } else { this.arrowStartElement.StartPoint = endPoint21; this.arrowElement.Points.Clear(); this.arrowElement.Points.Add(this.EndPoint); this.arrowElement.Points.Add(endPoint22); } } #endregion } else { #region 大弧 //直線の場合 if (this.IsBeeline) { double d1 = (endPoint11.X - this.StartPoint.X) * (endPoint11.X - this.StartPoint.X) + (endPoint11.Y - this.StartPoint.Y) * (endPoint11.Y - this.StartPoint.Y); double d2 = (endPoint21.X - this.StartPoint.X) * (endPoint21.X - this.StartPoint.X) + (endPoint21.Y - this.StartPoint.Y) * (endPoint21.Y - this.StartPoint.Y); if (d1 < d2) { this.arrowStartElement.StartPoint = endPoint11; this.arrowElement.Points.Clear(); this.arrowElement.Points.Add(this.EndPoint); this.arrowElement.Points.Add(endPoint12); } else { this.arrowStartElement.StartPoint = endPoint21; this.arrowElement.Points.Clear(); this.arrowElement.Points.Add(this.EndPoint); this.arrowElement.Points.Add(endPoint22); } } else { //点の位置を判定 if (MathExtension.GetPointLeftOrRight(_roundCenter, this.EndPoint, this.StartPoint) == (-1) * MathExtension.GetPointLeftOrRight(_roundCenter, this.EndPoint, centerPoint1)) { this.arrowStartElement.StartPoint = endPoint11; this.arrowElement.Points.Clear(); this.arrowElement.Points.Add(this.EndPoint); this.arrowElement.Points.Add(endPoint12); } else { this.arrowStartElement.StartPoint = endPoint21; this.arrowElement.Points.Clear(); this.arrowElement.Points.Add(this.EndPoint); this.arrowElement.Points.Add(endPoint22); } } #endregion } this.GetCenterPositen(_roundCenter); } }