Reputation: 125
In android , I have drawn an arc based on startangle, sweepangle and radius. Let width be 400 and height be 500 as rectangle bounds in which radius is calculated as
var radius = Math.Min(Width,Height)/2;
Also if centre is calculated as
var x = (float)(Width * 0.5);
var y = (float)(Height * 0.5);
var centre = new PointF(x,y);
If above centre value is used, centre remains same for all start angle and sweepangle for rectangle. I need to change the centre if startangle and sweep angle changes
In the below image, rectangle bounds is 400,500 and the startangle is 0 and sweepangle is 360
If I change start angle to 180 and sweepangle to 180, centre remains same
I need the below image output,if I change startangle and sweepangle based on circle bounds, centre point should vary
I have done calculations for the above ,
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;
}
This works when startangle and sweep angle changed for all cases except the case startangle 179 and sweep angle changed to above 180. case 3 includes the region 180,270,0 . how to write calculations for regions 3.
Any help is really appreciated.
Thanks in advance
Upvotes: 1
Views: 439
Reputation: 1976
When you want to draw an object
in the center of something
you should do this :
Object.Point =
new Point((something.Width / 2) - (object.Widht /2) ,(something.Height / 2) - object.Height / 2));
Upvotes: 0