You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
5.0 KiB

using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.Windows.Forms;
using System.Linq;
namespace GummingCommon
{
public class Radar
{
private double scale;
private float fixedvalue = 0;
public Bitmap DrawRegularPolygon(int width, int height, int angle, float[] dots, string[] names)
{
fixedvalue = 0;
Array.Reverse(names);//翻转后才可以和数据匹配上
int sides = dots.Length;
int margin = 30;
int radius = width / 2 - margin;
int space = radius / 6;
float minvalue = dots.Min();
if (minvalue < 0)
{
fixedvalue = Math.Abs(minvalue) + 1;
scale = radius * 1.0 / (dots.Max() + fixedvalue);
for (int i = 0; i < dots.Length; i++)
{
dots[i] = dots[i] + fixedvalue;
}
}
else
{
scale = radius * 1.0 / dots.Max();
}
Point center = new Point(width / 2, height / 2);
//Render the polygon
Bitmap polygon = new Bitmap(width, width);
using (Graphics g = Graphics.FromImage(polygon))
{
g.Clear(Color.FromArgb(255, 255, 255));
int spaces = space;
int steps = radius / space;
for (int i = 0; i < steps; i++)
{
Point[] verticies = CalculateVertices(sides, spaces, angle, center);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.DrawPolygon(new Pen(Color.FromArgb(200, 200, 200), 1), verticies);
g.DrawString(Math.Round(spaces / scale - fixedvalue, 2).ToString(), SystemFonts.DefaultFont, Brushes.Black, new Point() { X = verticies[verticies.Length - 1].X, Y = verticies[verticies.Length - 1].Y });
//g.DrawRectangle(new Pen(Color.FromArgb(220, 220, 220), 1), new Rectangle(center, new Size(1, 1)));
//foreach (var point in verticies)
//{
// g.DrawLine(new Pen(Color.FromArgb(220, 220, 220), 1), center, point);
//}
spaces = spaces + space;
if (i == steps - 1)
{
for (int j = 0; j < verticies.Length; j++)
{
int x = verticies[j].X;
int y = verticies[j].Y;
if (j == 0) { x = x - 20; } //左上角
if (j == 1) { x = x - 20; } //左下角
if (j == 2) { x = x + 20; } //右下角
if (j == 3) { x = x + 20; }//右上角
if (j == 4) { y = y - 20; }//上角
g.DrawString(names[j], SystemFonts.DefaultFont, Brushes.Black, new Point() { X = x, Y = y }, new StringFormat() { Alignment = StringAlignment.Center });
}
}
}
//Get the location for each vertex of the polygon
Point[] exportdots = CalculateVertices(sides, radius, angle, center, dots);
g.DrawPolygon(new Pen(Color.FromArgb(50, 205, 50), 1), exportdots);
}
return polygon;
}
private Point[] CalculateVertices(int sides, int radius, int startingAngle, Point center)
{
if (sides < 3)
throw new ArgumentException("at least 3 points.");
List<Point> points = new List<Point>();
float step = 360.0f / sides;
float angle = startingAngle;
for (int i = 0; i < sides; i++)
{
points.Add(DegreesToXY(angle, radius, center));
angle += step;
}
return points.ToArray();
}
private Point[] CalculateVertices(int sides, int radius, int startingAngle, Point center, float[] dots)
{
if (sides < 3)
throw new ArgumentException("at least 3 points.");
List<Point> points = new List<Point>();
float step = 360.0f / sides;
float angle = startingAngle;
for (int i = 0; i < sides; i++)
{
points.Add(DegreesToXY(angle, dots[sides - i - 1] * scale, center));
angle += step;
}
return points.ToArray();
}
private Point DegreesToXY(float degrees, double radius, Point origin)
{
Point xy = new Point();
double radians = degrees * Math.PI / 180.0;
xy.X = (int)(Math.Cos(radians) * radius + origin.X);
xy.Y = (int)(Math.Sin(-radians) * radius + origin.Y);
return xy;
}
}
}