Как расположить дугу от центра к внешним границам, если начальный угол и угол развертки изменились - PullRequest
0 голосов
/ 19 октября 2018

В андроиде я нарисовал дугу, основанную на начальном, круговом и радиусе.Пусть ширина равна 400, а высота равна 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 голосов
/ 19 октября 2018

Если ваш расчет хорошо работает для случаев, таких как 359-181, то вы можете повернуть дугу на 180 (начало + 180, конец + 180), рассчитать для нее сдвиг и отменить сдвиг (как dx, так и dy)

...