改变起始角和后掠角时如何找到中心点

时间:2018-10-17 10:03:25

标签: c# xamarin.android geometry algebra

在android中,我已经基于startangle,sweepangle和radius绘制了一条弧。假设width为400,height为500作为矩形边界,其中半径计算为

var radius =  Math.Min(Width,Height)/2;

如果将中心计算为

 var x = (float)(Width * 0.5);
 var y = (float)(Height * 0.5);

var centre = new PointF(x,y);

如果使用高于中心值,则矩形的所有起始角和后掠角的中心均保持不变。如果起始角和后掠角发生变化,我需要更改中心

在下图中,矩形边界为400,500,起始角为0,扫角为360

enter image description here

如果我将起始角度更改为180,并将后掠角度更改为180,则中心保持不变enter image description here

我需要下面的图像输出,如果我根据圆边界更改起始角和后掠角,则中心点应该会变化

enter image description here

我已经完成了上述计算,

private SystemPointF GetActualCenter(float x, float y, float radius)
        {
            SystemPointF actualCenter = new SystemPointF(x, y);
            double startAngle1 = GetWrapAngle(StartAngle, -630, 630);
            double endAngle1 = GetWrapAngle(EndAngle, -630, 630);
            float[] regions = new float[] { -630, -540, -450, -360, -270, -180, -90, 0, 90, 180, 270, 360, 450, 540, 630 };
            List<int> region = new List<int>();
            if (startAngle1 < endAngle1)
            {
                for (int i = 0; i < regions.Length; i++)
                {
                    if (regions[i] > startAngle1 && regions[i] < endAngle1)
                        region.Add((int)((regions[i] % 360) < 0 ? (regions[i] % 360) + 360 : (regions[i] % 360)));
                }
            }
            else
            {
                for (int i = 0; i < regions.Length; i++)
                {
                    if (regions[i] < startAngle1 && regions[i] > endAngle1)
                        region.Add((int)((regions[i] % 360) < 0 ? (regions[i] % 360) + 360 : (regions[i] % 360)));
                }
            }

            double startRadian = 2 * Math.PI * (startAngle1) / 360;
            double endRadian = 2 * Math.PI * (endAngle1) / 360;
            SystemPointF startPoint = new SystemPointF((float)(x + radius * Math.Cos(startRadian)),
                (float)(y + radius * Math.Sin(startRadian)));
            SystemPointF endPoint = new SystemPointF((float)(x + radius * Math.Cos(endRadian)),
                (float)(y + radius * Math.Sin(endRadian)));

            switch (region.Count)
            {
                case 0:
                    float longX = Math.Abs(x - startPoint.X) > Math.Abs(x - endPoint.X) ? startPoint.X : endPoint.X;
                    float longY = Math.Abs(y - startPoint.Y) > Math.Abs(y - endPoint.Y) ? startPoint.Y : endPoint.Y;
                    SystemPointF midPoint = new SystemPointF(Math.Abs((x + longX)) / 2, Math.Abs((y + longY)) / 2);
                    actualCenter.X = x + (x - midPoint.X);
                    actualCenter.Y = y + (y - midPoint.Y);
                    break;
                case 1:
                    SystemPointF point1 = new SystemPointF(), point2 = new SystemPointF();
                    float maxRadian = (float)(2 * Math.PI * region[0] / 360);
                    SystemPointF maxPoint = new SystemPointF((float)(x + radius * Math.Cos(maxRadian)),
                        (float)(y + radius * Math.Sin(maxRadian)));
                    switch (region[0])
                    {
                        case 270:
                            point1 = new SystemPointF(startPoint.X, maxPoint.Y);
                            point2 = new SystemPointF(endPoint.X, y);
                            break;
                        case 0:
                        case 360:
                            point1 = new SystemPointF(x, endPoint.Y);
                            point2 = new SystemPointF(maxPoint.X, startPoint.Y);
                            break;
                        case 90:
                            point1 = new SystemPointF(endPoint.X, y);
                            point2 = new SystemPointF(startPoint.X, maxPoint.Y);
                            break;
                        case 180:
                            point1 = new SystemPointF(maxPoint.X, startPoint.Y);
                            point2 = new SystemPointF(x, endPoint.Y);
                            break;
                    }
                    midPoint = new SystemPointF((point1.X + point2.X) / 2, (point1.Y + point2.Y) / 2);
                    actualCenter.X = x + ((x - midPoint.X) >= radius ? 0 : (x - midPoint.X));
                    actualCenter.Y = y + ((y - midPoint.Y) >= radius ? 0 : (y - midPoint.Y));
                    break;
                case 2:
                    float minRadian = (float)(2 * Math.PI * region[0] / 360);
                    maxRadian = (float)(2 * Math.PI * (region[1]) / 360);
                    maxPoint = new SystemPointF((float)(x + radius * Math.Cos(maxRadian)),
                        (float)(y + radius * Math.Sin(maxRadian)));
                    SystemPointF minPoint = new SystemPointF((float)(x + radius * Math.Cos(minRadian)),
                        (float)(y + radius * Math.Sin(minRadian)));
                    if (region[0] == 0 && region[1] == 90 || region[0] == 180
                        && region[1] == 270)
                        point1 = new SystemPointF(minPoint.X, maxPoint.Y);
                    else
                        point1 = new SystemPointF(maxPoint.X, minPoint.Y);
                    if (region[0] == 0 || region[0] == 180)
                        point2 = new SystemPointF(GetMinMaxValue(startPoint, endPoint, region[0]),
                            GetMinMaxValue(startPoint, endPoint, region[1]));
                    else
                        point2 = new SystemPointF(GetMinMaxValue(startPoint, endPoint, region[1]),
                            GetMinMaxValue(startPoint, endPoint, region[0]));
                    midPoint = new SystemPointF(Math.Abs(point1.X - point2.X) / 2 >= radius ? 0 : (point1.X + point2.X) / 2,
                        Math.Abs(point1.Y - point2.Y) / 2 >= radius ? 0 : (point1.Y + point2.Y) / 2);
                    actualCenter.X = x + (midPoint.X == 0 ? 0 : (x - midPoint.X) >= radius ? 0 : (x - midPoint.X));
                    actualCenter.Y = y + (midPoint.Y == 0 ? 0 : (y - midPoint.Y) >= radius ? 0 : (y - midPoint.Y));
                    break;
            }

            return actualCenter;
        }

在所有情况下起始角和后掠角均发生变化时,此方法有效,但情况下起始角179和后掠角变为180以上。情况3包含区域180,270,0。如何编写区域3的计算。

enter image description here

我们非常感谢您的帮助。

预先感谢

1 个答案:

答案 0 :(得分:0)

要在object的中心绘制something时,应该这样做:

Object.Point = 
new Point((something.Width / 2) - (object.Widht /2) ,(something.Height / 2) - object.Height / 2));