Ejemplo n.º 1
0
        /// <summary>
        /// 根据弧的起点,终点,半径,绘制方向,返回圆心点
        /// </summary>
        /// <param name="startPoint">点1</param>
        /// <param name="endPoint">点2</param>
        /// <param name="radius">半径</param>
        /// <param name="sweepDirection">绘制方向</param>
        /// <returns>坐标</returns>
        /// <!--作者: 韦腾 时间:2008.12.16-->
        public static Point GetRoundCenter(Point startPoint, Point endPoint, double radius, SweepDirection sweepDirection, bool isLargeArc)
        {
            if (startPoint == endPoint)
            {
                throw new Exception("起点与终点不能重合.");
            }

            //弧连线的长
            double width = Math.Sqrt((startPoint.Y - endPoint.Y) * (startPoint.Y - endPoint.Y) + (startPoint.X - endPoint.X) * (startPoint.X - endPoint.X));

            if (width / 2 > radius)
            {
                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();

            if (double.IsInfinity(k1))
            {
                roundCenterLeft  = new Point(crossingPoint.X + distance, crossingPoint.Y);
                roundCenterRight = new Point(crossingPoint.X - distance, crossingPoint.Y);
            }
            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);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 设置位置
        /// </summary>
        public void SetPosition()
        {
            #region 弧线
            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);
            #endregion

            #region 箭头
            Point  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;

            if (double.IsInfinity(k1)) //与Y轴平行
            {
                //中间点
                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.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));
                    }
                }
            }
            else if (Math.Round(k1, 4) == 0)//与X轴平行
            {
                //中间点
                this._CenterPoint.X = (this.StartPoint.X + this.EndPoint.X) / 2;
                this._CenterPoint.Y = (this.StartPoint.Y + this.EndPoint.Y) / 2;

                //如果是直线
                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;

                #region 第一个点
                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));
                #endregion

                #region 第二个点
                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));
                #endregion


                k2      = k1;
                xOffset = this.ArrowSize.Width / (Math.Sqrt(1 + k2 * k2));

                #region 第一个点对应的两个箭头端点
                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));
                #endregion

                #region 第二个点对应的两个箭头端点
                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));
                #endregion

                //小弧
                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);
            }
            #endregion
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 设置位置
        /// </summary>
        public void SetPosition()
        {
            #region 弧线
            lineElement.Point2 = new Point(EndPointX, EndPointY);
            LinePathFigureElement.StartPoint = new Point(StartPointX, StartPointY);

            #endregion

            #region 箭头
            Point  roundCenter = new Point();
            Point  textCenterPoint;
            double k1;
            //求圆心
            try
            {
                roundCenter = MathExtension.GetBezierCenter(LinePathFigureElement.StartPoint, lineElement.Point2, RadiusRadio * Length, this.LineSweepDirection);
                var cp = new Point()
                {
                    X = (StartPointX + EndPointX) / 2,
                    Y = (StartPointY + EndPointY) / 2,
                };

                textCenterPoint = new Point()
                {
                    X = (cp.X + roundCenter.X) / 2,
                    Y = (cp.Y + roundCenter.Y) / 2,
                };
                //圆心与箭头点连线的斜率
                k1 = (roundCenter.Y - this.EndPointY) / (roundCenter.X - this.EndPointX);
            }
            catch (Exception ex)
            {
                if (ex is RadiusException)
                {
                    k1 = (-1) * (this.StartPointX - this.EndPointX) / (this.StartPointY - this.EndPointY);
                    textCenterPoint = roundCenter = new Point()
                    {
                        X = (this.StartPointX + this.EndPointX) / 2,
                        Y = (this.StartPointY + this.EndPointY) / 2
                    };

                    SetLinePosition();
                    textBoxElement.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));

                    Canvas.SetLeft(textBoxElement, textCenterPoint.X - textBoxElement.DesiredSize.Width / 2);
                    Canvas.SetTop(textBoxElement, textCenterPoint.Y - textBoxElement.DesiredSize.Height / 2);
                    return;
                }
                else
                {
                    return;
                }
            }
            this.lineElement.Point1 = roundCenter;
            Point centerPoint1, centerPoint2, endPoint11, endPoint12, endPoint21, endPoint22;


            //切线斜率
            double k2 = 0;

            {
                k2 = k1;

                double xOffset = this.ArrowSize.Height / (Math.Sqrt(1 + k2 * k2));

                double xTemp, yTemp;

                #region 第一个点
                xTemp        = this.EndPointX + xOffset;
                yTemp        = k2 * (xTemp - this.EndPointX) + this.EndPointY;
                centerPoint1 = new Point(Math.Round(xTemp, 4), Math.Round(yTemp, 4));
                #endregion

                #region 第二个点
                xTemp        = this.EndPointX - xOffset;
                yTemp        = k2 * (xTemp - this.EndPointX) + this.EndPointY;
                centerPoint2 = new Point(Math.Round(xTemp, 4), Math.Round(yTemp, 4));
                #endregion

                k2 = (-1) / k1;

                xOffset = this.ArrowSize.Width / (Math.Sqrt(1 + k2 * k2));

                #region 第一个点对应的两个箭头端点
                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));
                #endregion

                #region 第二个点对应的两个箭头端点
                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));
                #endregion

                //小弧

                #region 永远找和圆心距离近的那组点

                {
                    double d1 = (endPoint11.X - roundCenter.X) * (endPoint11.X - roundCenter.X) + (endPoint11.Y - roundCenter.Y) * (endPoint11.Y - roundCenter.Y);
                    double d2 = (endPoint21.X - roundCenter.X) * (endPoint21.X - roundCenter.X) + (endPoint21.Y - roundCenter.Y) * (endPoint21.Y - roundCenter.Y);


                    //if (this.LineSweepDirection== SweepDirection.Clockwise)
                    if (d1 < d2)
                    {
                        this.arrowStartElement.StartPoint = endPoint11;
                        this.arrowElement.Points.Clear();
                        this.arrowElement.Points.Add(lineElement.Point2);
                        this.arrowElement.Points.Add(endPoint12);
                    }
                    else
                    {
                        this.arrowStartElement.StartPoint = endPoint21;
                        this.arrowElement.Points.Clear();
                        this.arrowElement.Points.Add(lineElement.Point2);
                        this.arrowElement.Points.Add(endPoint22);
                    }
                }
                #endregion
            }
            #endregion

            textBoxElement.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));

            Canvas.SetLeft(textBoxElement, textCenterPoint.X - textBoxElement.DesiredSize.Width / 2);
            Canvas.SetTop(textBoxElement, textCenterPoint.Y - textBoxElement.DesiredSize.Height / 2);
        }