增加PieChart通过ItemStyle设置边框的支持

This commit is contained in:
monitor1394
2020-04-08 09:02:46 +08:00
parent 26e67fb1a2
commit 3065b34ba6
8 changed files with 432 additions and 96 deletions

View File

@@ -1,6 +1,7 @@
# 更新日志
* (2020.04.08) 增加`PieChart`通过`ItemStyle`设置边框的支持
* (2020.03.29) 增加`Axis``ceilRate`设置最大最小值的取整倍率
* (2020.03.29) 增加`BarChart`可通过`itemStyle``cornerRadius`设置`圆角柱图`
* (2020.03.29) 增加`itemStyle``cornerRadius`支持圆角矩形

View File

@@ -194,6 +194,8 @@ namespace XCharts
ChartEditorHelper.MakeTwoField(ref drawRect, pos.width, m_Radius, "Radius");
EditorGUI.PropertyField(drawRect, m_RoundCap);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_ItemStyle);
drawRect.y += EditorGUI.GetPropertyHeight(m_ItemStyle);
EditorGUI.PropertyField(drawRect, m_Label);
drawRect.y += EditorGUI.GetPropertyHeight(m_Label);
EditorGUI.PropertyField(drawRect, m_Emphasis);
@@ -507,6 +509,7 @@ namespace XCharts
break;
case SerieType.Pie:
height += 9 * EditorGUIUtility.singleLineHeight + 8 * EditorGUIUtility.standardVerticalSpacing;
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_ItemStyle"));
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Label"));
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Emphasis"));
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Animation"));

View File

@@ -1,4 +1,5 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Collections.ObjectModel;
/******************************************/
/* */
/* Copyright (c) 2018 monitor1394 */
@@ -365,9 +366,9 @@ namespace XCharts
/// </summary>
internal void ClearValue()
{
runtimeDataIndex[0] = runtimeDataIndex[1] = -1;
runtimeXValues[0] = runtimeXValues[1] = -1;
runtimeYValues[0] = runtimeYValues[1] = -1;
for (int i = 0; i < runtimeDataIndex.Count; i++) runtimeDataIndex[i] = -1;
for (int i = 0; i < runtimeXValues.Length; i++) runtimeXValues[i] = -1;
for (int i = 0; i < runtimeYValues.Length; i++) runtimeYValues[i] = -1;
}
/// <summary>

View File

@@ -142,7 +142,7 @@ namespace XCharts
if (style == null) return GetItemStyle(serie, serieData, false);
else return style;
}
else if (serieData.enableItemStyle) return serieData.itemStyle;
else if (serieData != null && serieData.enableItemStyle) return serieData.itemStyle;
else return serie.itemStyle;
}
@@ -226,18 +226,18 @@ namespace XCharts
return color;
}
public static float GetSymbolBorder(Serie serie, SerieData serieData, bool highlight)
public static float GetSymbolBorder(Serie serie, SerieData serieData, bool highlight, bool useLineWidth = true)
{
var itemStyle = GetItemStyle(serie, serieData, highlight);
if (itemStyle != null && itemStyle.borderWidth != 0) return itemStyle.borderWidth;
else if (serie.lineStyle.width != 0) return serie.lineStyle.width;
else return 1;
else if (serie.lineStyle.width != 0 && useLineWidth) return serie.lineStyle.width;
else return 0;
}
public static float[] GetSymbolCornerRadius(Serie serie, SerieData serieData, bool highlight)
{
var itemStyle = GetItemStyle(serie, serieData, highlight);
if(itemStyle != null) return itemStyle.cornerRadius;
if (itemStyle != null) return itemStyle.cornerRadius;
else return null;
}
}

View File

@@ -145,6 +145,7 @@ namespace XCharts
var serie = series.GetSerie(i);
if (!serie.show) continue;
var serieData = serie.GetSerieData(dataIndex, dataZoom);
if (serieData == null) continue;
var itemFormatter = GetItemFormatter(tooltip, serie, serieData);
var percent = serieData.GetData(1) / serie.yTotal * 100;
needCategory = needCategory || (serie.type == SerieType.Line || serie.type == SerieType.Bar);

View File

@@ -82,13 +82,16 @@ namespace XCharts
for (int n = 0; n < data.Count; n++)
{
var serieData = data[n];
var itemStyle = SerieHelper.GetItemStyle(serie, serieData);
var itemStyle = SerieHelper.GetItemStyle(serie, serieData, serieData.highlighted);
serieData.index = n;
float value = serieData.GetCurrData(1, dataChangeDuration);
if (serieData.IsDataChanged()) dataChanging = true;
serieNameCount = m_LegendRealShowName.IndexOf(serieData.legendName);
var color = SerieHelper.GetItemColor(serie, serieData, m_ThemeInfo, serieNameCount, serieData.highlighted);
var toColor = SerieHelper.GetItemToColor(serie, serieData, m_ThemeInfo, serieNameCount, serieData.highlighted);
var borderWidth = itemStyle.borderWidth;
var borderColor = itemStyle.borderColor;
serieData.runtimePieStartAngle = startDegree;
serieData.runtimePieToAngle = startDegree;
serieData.runtimePieHalfAngle = startDegree;
@@ -109,7 +112,7 @@ namespace XCharts
isDataHighlight = true;
serieData.runtimePieOutsideRadius += m_Settings.pieTooltipExtraRadius;
}
var offset = serie.pieSpace;
var offset = 0f;
if (serie.pieClickOffset && serieData.selected)
{
offset += m_Settings.pieSelectedOffset;
@@ -131,7 +134,7 @@ namespace XCharts
}
if (offset > 0)
{
serieData.runtimePieOffsetRadius = serie.pieSpace / Mathf.Sin(halfDegree * Mathf.Deg2Rad);
serieData.runtimePieOffsetRadius = 0;
serieData.runtimePieInsideRadius -= serieData.runtimePieOffsetRadius;
serieData.runtimePieOutsideRadius -= serieData.runtimePieOffsetRadius;
if (serie.pieClickOffset && serieData.selected)
@@ -143,19 +146,19 @@ namespace XCharts
serieData.runtiemPieOffsetCenter = new Vector3(center.x + serieData.runtimePieOffsetRadius * currSin,
center.y + serieData.runtimePieOffsetRadius * currCos);
var drawStartDegree = startDegree + serie.pieSpace;
var drawEndDegree = serieData.runtimePieCurrAngle - serie.pieSpace;
DrawRoundCap(vh, serie, serieData, serieData.runtiemPieOffsetCenter, color, ref drawStartDegree, ref drawEndDegree);
ChartDrawer.DrawDoughnut(vh, serieData.runtiemPieOffsetCenter, serieData.runtimePieInsideRadius, serieData.runtimePieOutsideRadius,
color, toColor, m_ThemeInfo.backgroundColor, m_Settings.cicleSmoothness, drawStartDegree, drawEndDegree);
var drawEndDegree = serieData.runtimePieCurrAngle;
var needRoundCap = serie.roundCap && serieData.runtimePieInsideRadius > 0;
ChartDrawer.DrawDoughnut(vh, serieData.runtiemPieOffsetCenter, serieData.runtimePieInsideRadius,
serieData.runtimePieOutsideRadius, color, toColor, Color.clear, startDegree, drawEndDegree,
borderWidth, borderColor, serie.pieSpace / 2, m_Settings.cicleSmoothness, needRoundCap, serie.clockwise);
}
else
else //if(n==0)
{
var drawStartDegree = startDegree + serie.pieSpace;
var drawEndDegree = serieData.runtimePieCurrAngle - serie.pieSpace;
DrawRoundCap(vh, serie, serieData, center, color, ref drawStartDegree, ref drawEndDegree);
var drawEndDegree = serieData.runtimePieCurrAngle;
var needRoundCap = serie.roundCap && serieData.runtimePieInsideRadius > 0;
ChartDrawer.DrawDoughnut(vh, center, serieData.runtimePieInsideRadius, serieData.runtimePieOutsideRadius,
color, toColor, Color.clear, m_Settings.cicleSmoothness, drawStartDegree, drawEndDegree);
color, toColor, Color.clear, startDegree, drawEndDegree, borderWidth, borderColor, serie.pieSpace / 2,
m_Settings.cicleSmoothness, needRoundCap, serie.clockwise);
DrawCenter(vh, serie, itemStyle, serieData.runtimePieInsideRadius);
}
serieData.canShowLabel = serieData.runtimePieCurrAngle >= serieData.runtimePieHalfAngle;
@@ -189,22 +192,6 @@ namespace XCharts
}
}
private void DrawRoundCap(VertexHelper vh, Serie serie, SerieData serieData, Vector3 centerPos,
Color color, ref float drawStartDegree, ref float drawEndDegree)
{
if (serie.roundCap && serieData.runtimePieInsideRadius > 0)
{
var width = (serieData.runtimePieOutsideRadius - serieData.runtimePieInsideRadius) / 2;
var radius = serieData.runtimePieInsideRadius + width;
var diffDegree = Mathf.Asin(width / radius) * Mathf.Rad2Deg;
drawStartDegree += diffDegree;
drawEndDegree -= diffDegree;
ChartDrawer.DrawRoundCap(vh, centerPos, width, radius, drawStartDegree, serie.clockwise, color, false);
ChartDrawer.DrawRoundCap(vh, centerPos, width, radius, drawEndDegree, serie.clockwise, color, true);
}
}
private void DrawLabelLine(VertexHelper vh)
{
foreach (var serie in m_Series.list)

View File

@@ -89,23 +89,22 @@ namespace XCharts
var degree = 360 * value / max;
var startDegree = GetStartAngle(serie);
var toDegree = GetToAngle(serie, degree);
var itemStyle = SerieHelper.GetItemStyle(serie, serieData, serieData.highlighted);
var itemColor = SerieHelper.GetItemColor(serie, serieData, m_ThemeInfo, j, serieData.highlighted);
var outsideRadius = serie.runtimeOutsideRadius - j * (ringWidth + serie.ringGap);
var insideRadius = outsideRadius - ringWidth;
var centerRadius = (outsideRadius + insideRadius) / 2;
var borderWidth = itemStyle.borderWidth;
var borderColor = itemStyle.borderColor;
var roundCap = serie.roundCap && insideRadius > 0;
serieData.runtimePieStartAngle = serie.clockwise ? startDegree : toDegree;
serieData.runtimePieToAngle = serie.clockwise ? toDegree : startDegree;
serieData.runtimePieInsideRadius = insideRadius;
serieData.runtimePieOutsideRadius = outsideRadius;
DrawBackground(vh, serie, serieData, j, insideRadius, outsideRadius);
DrawRoundCap(vh, serie, serie.runtimeCenterPos, itemColor, insideRadius, outsideRadius,
ref startDegree, ref toDegree);
ChartDrawer.DrawDoughnut(vh, serie.runtimeCenterPos, insideRadius,
outsideRadius, itemColor, Color.clear, m_Settings.cicleSmoothness,
startDegree, toDegree);
DrawBorder(vh, serie, serieData, insideRadius, outsideRadius);
ChartDrawer.DrawDoughnut(vh, serie.runtimeCenterPos, insideRadius, outsideRadius, itemColor, itemColor,
Color.clear, startDegree, toDegree, borderWidth, borderColor, 0, m_Settings.cicleSmoothness,
roundCap, serie.clockwise);
DrawCenter(vh, serie, serieData, insideRadius, j == data.Count - 1);
UpateLabelPosition(serie, serieData, j, startDegree, toDegree, centerRadius);
}
@@ -132,7 +131,7 @@ namespace XCharts
var toAngle = angle + serie.startAngle;
if (!serie.clockwise)
{
toAngle = 360 - toAngle - serie.startAngle;
toAngle = 360 - angle - serie.startAngle;
}
if (!serie.animation.IsFinish())
{

View File

@@ -434,7 +434,7 @@ namespace XCharts
if (brLt > 0)
{
tempCenter = new Vector3(center.x - halfWid + brLt, center.y + halfHig - brLt);
DrawDoughnut(vh, tempCenter, brLt, brLt + borderWidth, color, Color.clear, 2, 270, 360);
DrawDoughnut(vh, tempCenter, brLt, brLt + borderWidth, color, Color.clear, 270, 360);
ltIn = tempCenter + brLt * Vector3.left;
ltOt = tempCenter + (brLt + borderWidth) * Vector3.left;
ltIn2 = tempCenter + brLt * Vector3.up;
@@ -443,7 +443,7 @@ namespace XCharts
if (brRt > 0)
{
tempCenter = new Vector3(center.x + halfWid - brRt, center.y + halfHig - brRt);
DrawDoughnut(vh, tempCenter, brRt, brRt + borderWidth, color, Color.clear, 2, 0, 90);
DrawDoughnut(vh, tempCenter, brRt, brRt + borderWidth, color, Color.clear, 0, 90);
rtIn = tempCenter + brRt * Vector3.up;
rtOt = tempCenter + (brRt + borderWidth) * Vector3.up;
rtIn2 = tempCenter + brRt * Vector3.right;
@@ -452,7 +452,7 @@ namespace XCharts
if (brRb > 0)
{
tempCenter = new Vector3(center.x + halfWid - brRb, center.y - halfHig + brRb);
DrawDoughnut(vh, tempCenter, brRb, brRb + borderWidth, color, Color.clear, 2, 90, 180);
DrawDoughnut(vh, tempCenter, brRb, brRb + borderWidth, color, Color.clear, 90, 180);
rbIn = tempCenter + brRb * Vector3.right;
rbOt = tempCenter + (brRb + borderWidth) * Vector3.right;
rbIn2 = tempCenter + brRb * Vector3.down;
@@ -461,7 +461,7 @@ namespace XCharts
if (brLb > 0)
{
tempCenter = new Vector3(center.x - halfWid + brLb, center.y - halfHig + brLb);
DrawDoughnut(vh, tempCenter, brLb, brLb + borderWidth, color, Color.clear, 2, 180, 270);
DrawDoughnut(vh, tempCenter, brLb, brLb + borderWidth, color, Color.clear, 180, 270);
lbIn = tempCenter + brLb * Vector3.left;
lbOt = tempCenter + (brLb + borderWidth) * Vector3.left;
lbIn2 = tempCenter + brLb * Vector3.down;
@@ -536,51 +536,166 @@ namespace XCharts
}
public static void DrawCricle(VertexHelper vh, Vector3 p, float radius, Color32 color,
Color32 toColor, float smoothness = 2f)
float smoothness = 2f)
{
DrawSector(vh, p, radius, color, toColor, 0, 360, smoothness);
DrawCricle(vh, p, radius, color, color, 0, Color.clear, smoothness);
}
public static void DrawCricle(VertexHelper vh, Vector3 p, float radius, Color32 color,
Color32 toColor, float smoothness = 2f)
{
DrawSector(vh, p, radius, color, toColor, 0, 360, 0, Color.clear, smoothness);
}
public static void DrawCricle(VertexHelper vh, Vector3 p, float radius, Color32 color,
Color32 toColor, float borderWidth, Color32 borderColor, float smoothness = 2f)
{
DrawSector(vh, p, radius, color, toColor, 0, 360, borderWidth, borderColor, smoothness);
}
public static void DrawCricle(VertexHelper vh, Vector3 p, float radius, Color32 color,
float borderWidth, Color32 borderColor, float smoothness = 2f)
{
DrawCricle(vh, p, radius, color, color, borderWidth, borderColor, smoothness);
}
public static void DrawEmptyCricle(VertexHelper vh, Vector3 p, float radius, float tickness,
Color32 color, Color32 emptyColor, float smoothness = 2f)
{
DrawDoughnut(vh, p, radius - tickness, radius, color, color, emptyColor, 0, 360, 0, Color.clear, 0, smoothness);
}
public static void DrawEmptyCricle(VertexHelper vh, Vector3 p, float radius, float tickness,
Color32 color, Color32 emptyColor, float borderWidth, Color32 borderColor, float smoothness = 2f)
{
DrawDoughnut(vh, p, radius - tickness, radius, color, color, emptyColor, 0, 360, borderWidth,
borderColor, 0, smoothness);
}
public static void DrawEmptyCricle(VertexHelper vh, Vector3 p, float radius, float tickness,
Color32 color, Color32 toColor, Color32 emptyColor, float smoothness = 2f)
{
DrawDoughnut(vh, p, radius - tickness, radius, color, toColor, emptyColor, 0, 360, 0,
Color.clear, 0, smoothness);
}
public static void DrawEmptyCricle(VertexHelper vh, Vector3 p, float radius, float tickness,
Color32 color, Color32 toColor, Color32 emptyColor, float borderWidth, Color32 borderColor,
float smoothness = 2f)
{
DrawCricle(vh, p, radius, color, color, smoothness);
}
public static void DrawEmptyCricle(VertexHelper vh, Vector3 p, float radius, float tickness,
Color32 color, Color emptyColor, float smoothness = 2f)
{
DrawDoughnut(vh, p, radius - tickness, radius, color, color, emptyColor, smoothness);
}
public static void DrawEmptyCricle(VertexHelper vh, Vector3 p, float radius, float tickness,
Color32 color, Color32 toColor, Color emptyColor, float smoothness = 2f)
{
DrawDoughnut(vh, p, radius - tickness, radius, color, toColor, emptyColor, smoothness);
DrawDoughnut(vh, p, radius - tickness, radius, color, toColor, emptyColor, 0, 360, borderWidth,
borderColor, 0, smoothness);
}
public static void DrawSector(VertexHelper vh, Vector3 p, float radius, Color32 color,
float startDegree, float toDegree, float smoothness = 2f)
float startDegree, float toDegree, float smoothness = 2f)
{
DrawSector(vh, p, radius, color, color, startDegree, toDegree, smoothness);
DrawSector(vh, p, radius, color, color, startDegree, toDegree, 0, Color.clear, smoothness);
}
public static void DrawSector(VertexHelper vh, Vector3 p, float radius, Color32 color, Color32 toColor,
float startDegree, float toDegree, float smoothness = 2f)
{
DrawSector(vh, p, radius, color, toColor, startDegree, toDegree, 0, Color.clear, smoothness);
}
public static void DrawSector(VertexHelper vh, Vector3 p, float radius, Color32 color,
Color32 toColor, float startDegree, float toDegree, float smoothness = 2f)
float startDegree, float toDegree, float borderWidth, Color32 borderColor, float smoothness = 2f)
{
int segments = (int)((2 * Mathf.PI * radius) / (smoothness < 0 ? 2f : smoothness));
Vector3 p2, p3;
DrawSector(vh, p, radius, color, color, startDegree, toDegree, borderWidth, borderColor, smoothness);
}
public static void DrawSector(VertexHelper vh, Vector3 p, float radius, Color32 color, Color32 toColor,
float startDegree, float toDegree, float borderWidth, Color32 borderColor, float smoothness = 2f)
{
DrawSector(vh, p, radius, color, toColor, startDegree, toDegree, borderWidth, borderColor, 0, smoothness);
}
public static void DrawSector(VertexHelper vh, Vector3 p, float radius, Color32 color, Color32 toColor,
float startDegree, float toDegree, float borderWidth, Color32 borderColor, float space,
float smoothness = 2f)
{
radius -= borderWidth;
smoothness = (smoothness < 0 ? 2f : smoothness);
int segments = (int)((2 * Mathf.PI * radius) * (Mathf.Abs(toDegree - startDegree) / 360) / smoothness);
float startAngle = startDegree * Mathf.Deg2Rad;
float angle = (toDegree - startDegree) * Mathf.Deg2Rad / segments;
p2 = new Vector3(p.x + radius * Mathf.Sin(startAngle), p.y + radius * Mathf.Cos(startAngle));
float toAngle = toDegree * Mathf.Deg2Rad;
float realStartAngle = startAngle;
float realToAngle = toAngle;
float halfAngle = (toAngle - startAngle) / 2;
float borderAngle = 0;
float spaceAngle = 0;
var p2 = p + radius * GetDire(startAngle);
var p3 = Vector3.zero;
var spaceCenter = p;
var realCenter = p;
var needBorder = borderWidth != 0;
var needSpace = space != 0;
var lastPos = Vector3.zero;
var middleDire = GetDire(startAngle + halfAngle);
if (needBorder || needSpace)
{
float spaceDiff = 0f;
float borderDiff = 0f;
if (needSpace)
{
spaceDiff = space / Mathf.Sin(halfAngle);
spaceCenter = p + spaceDiff * middleDire;
realCenter = spaceCenter;
spaceAngle = 2 * Mathf.Asin(space / (2 * radius));
realStartAngle = startAngle + spaceAngle;
realToAngle = toAngle - spaceAngle;
p2 = GetPos(p, radius, realStartAngle);
}
if (needBorder)
{
borderDiff = borderWidth / Mathf.Sin(halfAngle);
realCenter += borderDiff * middleDire;
borderAngle = 2 * Mathf.Asin(borderWidth / (2 * radius));
realStartAngle = realStartAngle + borderAngle;
var borderX1 = GetPos(p, radius, realStartAngle);
DrawPolygon(vh, realCenter, spaceCenter, p2, borderX1, borderColor);
p2 = borderX1;
realToAngle = realToAngle - borderAngle;
var borderX2 = GetPos(p, radius, realToAngle);
var pEnd = GetPos(p, radius, toAngle - spaceAngle);
DrawPolygon(vh, realCenter, borderX2, pEnd, spaceCenter, borderColor);
}
}
float segmentAngle = (realToAngle - realStartAngle) / segments;
for (int i = 0; i <= segments; i++)
{
float currAngle = startAngle + i * angle;
p3 = new Vector3(p.x + radius * Mathf.Sin(currAngle),
p.y + radius * Mathf.Cos(currAngle));
DrawTriangle(vh, p, p2, p3, toColor, color, color);
float currAngle = realStartAngle + i * segmentAngle;
p3 = p + radius * GetDire(currAngle);
DrawTriangle(vh, realCenter, p2, p3, toColor, color, color);
p2 = p3;
}
if (needBorder || needSpace)
{
var borderX2 = p + radius * GetDire(realToAngle);
DrawTriangle(vh, realCenter, p2, borderX2, toColor, color, color);
if (needBorder)
{
var realStartDegree = (realStartAngle - borderAngle) * Mathf.Rad2Deg;
var realToDegree = (realToAngle + borderAngle) * Mathf.Rad2Deg;
DrawDoughnut(vh, p, radius, radius + borderWidth, borderColor, Color.clear, realStartDegree,
realToDegree, smoothness);
}
}
}
private static Vector3 GetPos(Vector3 center, float radius, float angle, bool isDegree = false)
{
angle = isDegree ? angle * Mathf.Deg2Rad : angle;
return new Vector3(center.x + radius * Mathf.Sin(angle), center.y + radius * Mathf.Cos(angle));
}
private static Vector3 GetDire(float angle, bool isDegree = false)
{
angle = isDegree ? angle * Mathf.Deg2Rad : angle;
return new Vector3(Mathf.Sin(angle), Mathf.Cos(angle));
}
public static void DrawRoundCap(VertexHelper vh, Vector3 center, float width, float radius, float angle,
@@ -592,56 +707,285 @@ namespace XCharts
if (end)
{
if (clockwise)
ChartDrawer.DrawSector(vh, pos, width, color, angle, angle + 180);
ChartDrawer.DrawSector(vh, pos, width, color, angle, angle + 180, 0, Color.clear);
else
ChartDrawer.DrawSector(vh, pos, width, color, angle, angle - 180);
ChartDrawer.DrawSector(vh, pos, width, color, angle, angle - 180, 0, Color.clear);
}
else
{
if (clockwise)
ChartDrawer.DrawSector(vh, pos, width, color, angle + 180, angle + 360);
ChartDrawer.DrawSector(vh, pos, width, color, angle + 180, angle + 360, 0, Color.clear);
else
ChartDrawer.DrawSector(vh, pos, width, color, angle - 180, angle - 360);
ChartDrawer.DrawSector(vh, pos, width, color, angle - 180, angle - 360, 0, Color.clear);
}
}
public static void DrawDoughnut(VertexHelper vh, Vector3 p, float insideRadius, float outsideRadius,
Color32 color, Color emptyColor, float smoothness = 2f, float startDegree = 0, float toDegree = 360)
Color32 color, Color emptyColor, float smoothness = 2f)
{
DrawDoughnut(vh, p, insideRadius, outsideRadius, color, color, emptyColor, smoothness,
startDegree, toDegree);
DrawDoughnut(vh, p, insideRadius, outsideRadius, color, color, emptyColor, 0, 360, 0, Color.clear,
0, smoothness);
}
public static void DrawDoughnut(VertexHelper vh, Vector3 p, float insideRadius, float outsideRadius,
Color32 color, Color32 toColor, Color emptyColor, float smoothness = 2f, float startDegree = 0,
float toDegree = 360)
Color32 color, Color emptyColor, float startDegree,
float toDegree, float smoothness = 2f)
{
DrawDoughnut(vh, p, insideRadius, outsideRadius, color, color, emptyColor, startDegree, toDegree,
0, Color.clear, 0, smoothness);
}
public static void DrawDoughnut(VertexHelper vh, Vector3 p, float insideRadius, float outsideRadius,
Color32 color, Color emptyColor, float startDegree,
float toDegree, float borderWidth, Color32 borderColor, float smoothness = 2f)
{
DrawDoughnut(vh, p, insideRadius, outsideRadius, color, color, emptyColor, startDegree, toDegree,
borderWidth, borderColor, 0, smoothness);
}
public static void DrawDoughnut(VertexHelper vh, Vector3 p, float insideRadius, float outsideRadius,
Color32 color, Color32 toColor, Color emptyColor, float smoothness = 2f)
{
DrawDoughnut(vh, p, insideRadius, outsideRadius, color, toColor, emptyColor, 0, 360, 0, Color.clear,
0, smoothness);
}
public static void DrawDoughnut(VertexHelper vh, Vector3 p, float insideRadius, float outsideRadius,
Color32 color, Color32 toColor, Color emptyColor, float startDegree, float toDegree, float borderWidth,
Color32 borderColor, float space, float smoothness, bool roundCap = false, bool clockwise = true)
{
if (toDegree - startDegree == 0) return;
if (insideRadius <= 0)
{
DrawSector(vh, p, outsideRadius, color, toColor, startDegree, toDegree, smoothness);
DrawSector(vh, p, outsideRadius, color, toColor, startDegree, toDegree, borderWidth, borderColor,
space, smoothness);
return;
}
Vector3 p1, p2, p3, p4;
int segments = (int)((2 * Mathf.PI * outsideRadius) / (smoothness < 0 ? 2f : smoothness));
outsideRadius -= borderWidth;
insideRadius += borderWidth;
smoothness = smoothness < 0 ? 2f : smoothness;
Vector3 p1, p2, p3, p4, e1, e2;
var needBorder = borderWidth != 0;
var needSpace = space != 0;
var diffAngle = Mathf.Abs(toDegree - startDegree) * Mathf.Deg2Rad;
int segments = (int)((2 * Mathf.PI * outsideRadius) * (diffAngle * Mathf.Rad2Deg / 360) / smoothness);
float startAngle = startDegree * Mathf.Deg2Rad;
float angle = (toDegree - startDegree) * Mathf.Deg2Rad / segments;
p1 = new Vector3(p.x + insideRadius * Mathf.Sin(startAngle),
p.y + insideRadius * Mathf.Cos(startAngle));
p2 = new Vector3(p.x + outsideRadius * Mathf.Sin(startAngle),
p.y + outsideRadius * Mathf.Cos(startAngle));
float toAngle = toDegree * Mathf.Deg2Rad;
float realStartOutAngle = startAngle;
float realToOutAngle = toAngle;
float realStartInAngle = startAngle;
float realToInAngle = toAngle;
float halfAngle = (toAngle - startAngle) / 2;
float borderAngle = 0, borderInAngle = 0, borderHalfAngle = 0;
float spaceAngle = 0, spaceInAngle = 0, spaceHalfAngle = 0;
var spaceCenter = p;
var realCenter = p;
var startDire = new Vector3(Mathf.Sin(startAngle), Mathf.Cos(startAngle)).normalized;
var toDire = new Vector3(Mathf.Sin(toAngle), Mathf.Cos(toAngle)).normalized;
var middleDire = new Vector3(Mathf.Sin(startAngle + halfAngle), Mathf.Cos(startAngle + halfAngle)).normalized;
p1 = p + insideRadius * startDire;
p2 = p + outsideRadius * startDire;
e1 = p + insideRadius * toDire;
e2 = p + outsideRadius * toDire;
if (roundCap)
{
var roundRadius = (outsideRadius - insideRadius) / 2;
var roundAngleRadius = insideRadius + roundRadius;
var roundAngle = Mathf.Atan(roundRadius / roundAngleRadius);
if (diffAngle < 2 * roundAngle)
{
roundCap = false;
}
}
if (needBorder || needSpace)
{
if (needSpace)
{
var spaceDiff = space / Mathf.Sin(halfAngle);
spaceCenter = p + Mathf.Abs(spaceDiff) * middleDire;
realCenter = spaceCenter;
spaceAngle = 2 * Mathf.Asin(space / (2 * outsideRadius));
spaceInAngle = 2 * Mathf.Asin(space / (2 * insideRadius));
spaceHalfAngle = 2 * Mathf.Asin(space / (2 * (insideRadius + (outsideRadius - insideRadius) / 2)));
if (clockwise)
{
p1 = GetPos(p, insideRadius, startAngle + spaceInAngle, false);
e1 = GetPos(p, insideRadius, toAngle - spaceInAngle, false);
realStartOutAngle = startAngle + spaceAngle;
realToOutAngle = toAngle - spaceAngle;
realStartInAngle = startAngle + spaceInAngle;
realToInAngle = toAngle - spaceInAngle;
}
else
{
p1 = GetPos(p, insideRadius, startAngle - spaceInAngle, false);
e1 = GetPos(p, insideRadius, toAngle + spaceInAngle, false);
realStartOutAngle = startAngle - spaceAngle;
realToOutAngle = toAngle + spaceAngle;
realStartInAngle = startAngle - spaceInAngle;
realToOutAngle = toAngle + spaceInAngle;
}
p2 = GetPos(p, outsideRadius, realStartOutAngle, false);
e2 = GetPos(p, outsideRadius, realToOutAngle, false);
}
if (needBorder)
{
var borderDiff = borderWidth / Mathf.Sin(halfAngle);
realCenter += Mathf.Abs(borderDiff) * middleDire;
borderAngle = 2 * Mathf.Asin(borderWidth / (2 * outsideRadius));
borderInAngle = 2 * Mathf.Asin(borderWidth / (2 * insideRadius));
borderHalfAngle = 2 * Mathf.Asin(borderWidth / (2 * (insideRadius + (outsideRadius - insideRadius) / 2)));
if (clockwise)
{
realStartOutAngle = realStartOutAngle + borderAngle;
realToOutAngle = realToOutAngle - borderAngle;
realStartInAngle = startAngle + spaceInAngle + borderInAngle;
realToInAngle = toAngle - spaceInAngle - borderInAngle;
var newp1 = GetPos(p, insideRadius, startAngle + spaceInAngle + borderInAngle, false);
var newp2 = GetPos(p, outsideRadius, realStartOutAngle, false);
if (!roundCap) DrawPolygon(vh, newp2, newp1, p1, p2, borderColor);
p1 = newp1;
p2 = newp2;
if (toAngle - spaceInAngle - 2 * borderInAngle > realStartOutAngle)
{
var newe1 = GetPos(p, insideRadius, toAngle - spaceInAngle - borderInAngle, false);
var newe2 = GetPos(p, outsideRadius, realToOutAngle, false);
if (!roundCap) DrawPolygon(vh, newe2, e2, e1, newe1, borderColor);
e1 = newe1;
e2 = newe2;
}
}
else
{
realStartOutAngle = realStartOutAngle - borderAngle;
realToOutAngle = realToOutAngle + borderAngle;
realStartInAngle = startAngle - spaceInAngle - borderInAngle;
realToInAngle = toAngle + spaceInAngle + borderInAngle;
var newp1 = GetPos(p, insideRadius, startAngle - spaceInAngle - borderInAngle, false);
var newp2 = GetPos(p, outsideRadius, realStartOutAngle, false);
if (!roundCap) DrawPolygon(vh, newp2, newp1, p1, p2, borderColor);
p1 = newp1;
p2 = newp2;
if (toAngle + spaceInAngle + 2 * borderInAngle < realStartOutAngle)
{
var newe1 = GetPos(p, insideRadius, toAngle + spaceInAngle + borderInAngle, false);
var newe2 = GetPos(p, outsideRadius, realToOutAngle, false);
if (!roundCap) DrawPolygon(vh, newe2, e2, e1, newe1, borderColor);
e1 = newe1;
e2 = newe2;
}
}
}
}
if (roundCap)
{
var roundRadius = (outsideRadius - insideRadius) / 2;
var roundAngleRadius = insideRadius + roundRadius;
var roundAngle = Mathf.Atan(roundRadius / roundAngleRadius);
if (clockwise)
{
realStartOutAngle = startAngle + 2 * spaceHalfAngle + borderHalfAngle + roundAngle;
realStartInAngle = startAngle + 2 * spaceHalfAngle + borderHalfAngle + roundAngle;
}
else
{
realStartOutAngle = startAngle - 2 * spaceHalfAngle - borderHalfAngle - roundAngle;
realStartInAngle = startAngle - 2 * spaceHalfAngle - borderHalfAngle - roundAngle;
}
var roundTotalDegree = realStartOutAngle * Mathf.Rad2Deg;
var roundCenter = p + roundAngleRadius * GetDire(realStartOutAngle);
var sectorStartDegree = clockwise ? roundTotalDegree + 180 : roundTotalDegree;
var sectorToDegree = clockwise ? roundTotalDegree + 360 : roundTotalDegree + 180;
DrawSector(vh, roundCenter, roundRadius, color, sectorStartDegree, sectorToDegree, smoothness / 2);
if (needBorder)
{
DrawDoughnut(vh, roundCenter, roundRadius, roundRadius + borderWidth, borderColor, Color.clear,
sectorStartDegree, sectorToDegree, smoothness / 2);
}
p1 = GetPos(p, insideRadius, realStartOutAngle);
p2 = GetPos(p, outsideRadius, realStartOutAngle);
if (clockwise)
{
realToOutAngle = toAngle - 2 * spaceHalfAngle - borderHalfAngle - roundAngle;
realToInAngle = toAngle - 2 * spaceHalfAngle - borderHalfAngle - roundAngle;
if (realToOutAngle < realStartOutAngle) realToOutAngle = realStartOutAngle;
}
else
{
realToOutAngle = toAngle + 2 * spaceHalfAngle + borderHalfAngle + roundAngle;
realToInAngle = toAngle + 2 * spaceHalfAngle + borderHalfAngle + roundAngle;
if (realToOutAngle > realStartOutAngle) realToOutAngle = realStartOutAngle;
}
roundTotalDegree = realToOutAngle * Mathf.Rad2Deg;
roundCenter = p + roundAngleRadius * GetDire(realToOutAngle);
sectorStartDegree = clockwise ? roundTotalDegree : roundTotalDegree + 180;
sectorToDegree = clockwise ? roundTotalDegree + 180 : roundTotalDegree + 360;
DrawSector(vh, roundCenter, roundRadius, color, sectorStartDegree, sectorToDegree, smoothness / 2);
if (needBorder)
{
DrawDoughnut(vh, roundCenter, roundRadius, roundRadius + borderWidth, borderColor, Color.clear,
sectorStartDegree, sectorToDegree, smoothness / 2);
}
e1 = GetPos(p, insideRadius, realToOutAngle);
e2 = GetPos(p, outsideRadius, realToOutAngle);
}
float segmentAngle = (realToInAngle - realStartInAngle) / segments;
for (int i = 0; i <= segments; i++)
{
float currAngle = startAngle + i * angle;
float currAngle = realStartInAngle + i * segmentAngle;
p3 = new Vector3(p.x + outsideRadius * Mathf.Sin(currAngle),
p.y + outsideRadius * Mathf.Cos(currAngle));
p4 = new Vector3(p.x + insideRadius * Mathf.Sin(currAngle),
p.y + insideRadius * Mathf.Cos(currAngle));
if (emptyColor != Color.clear) DrawTriangle(vh, p, p1, p4, emptyColor);
//DrawPolygon(vh, p1, p2, p3, p4, color,Color.blue);
DrawPolygon(vh, p2, p3, p4, p1, color, toColor);
p1 = p4;
p2 = p3;
}
if (needBorder || needSpace || roundCap)
{
if (clockwise)
{
var isInAngleFixed = toAngle - spaceInAngle - 2 * borderInAngle > realStartOutAngle;
if (isInAngleFixed) DrawPolygon(vh, p2, e2, e1, p1, color, toColor);
else DrawTriangle(vh, p2, e2, p1, color, color, toColor);
if (needBorder)
{
var realStartDegree = (realStartOutAngle - (roundCap ? 0 : borderAngle)) * Mathf.Rad2Deg;
var realToDegree = (realToOutAngle + (roundCap ? 0 : borderAngle)) * Mathf.Rad2Deg;
if (realToDegree < realStartOutAngle) realToDegree = realStartOutAngle;
var inStartDegree = roundCap ? realStartDegree : (startAngle + spaceInAngle) * Mathf.Rad2Deg;
var inToDegree = roundCap ? realToDegree : (toAngle - spaceInAngle) * Mathf.Rad2Deg;
if (inToDegree < inStartDegree) inToDegree = inStartDegree;
if (isInAngleFixed) DrawDoughnut(vh, p, insideRadius - borderWidth, insideRadius, borderColor, Color.clear,
inStartDegree, inToDegree, smoothness);
DrawDoughnut(vh, p, outsideRadius, outsideRadius + borderWidth, borderColor, Color.clear,
realStartDegree, realToDegree, smoothness);
}
}
else
{
var isInAngleFixed = toAngle + spaceInAngle + 2 * borderInAngle < realStartOutAngle;
if (isInAngleFixed) DrawPolygon(vh, p2, e2, e1, p1, color, toColor);
else DrawTriangle(vh, p2, e2, p1, color, color, toColor);
if (needBorder)
{
var realStartDegree = (realStartOutAngle + (roundCap ? 0 : borderAngle)) * Mathf.Rad2Deg;
var realToDegree = (realToOutAngle - (roundCap ? 0 : borderAngle)) * Mathf.Rad2Deg;
var inStartDegree = roundCap ? realStartDegree : (startAngle - spaceInAngle) * Mathf.Rad2Deg;
var inToDegree = roundCap ? realToDegree : (toAngle + spaceInAngle) * Mathf.Rad2Deg;
if (inToDegree > inStartDegree) inToDegree = inStartDegree;
if (isInAngleFixed) DrawDoughnut(vh, p, insideRadius - borderWidth, insideRadius, borderColor, Color.clear,
inStartDegree, inToDegree, smoothness);
DrawDoughnut(vh, p, outsideRadius, outsideRadius + borderWidth, borderColor, Color.clear,
realStartDegree, realToDegree, smoothness);
}
}
}
}
/// <summary>