525 lines
17 KiB
C#
525 lines
17 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Drawing;
|
|
using System.Collections.Generic;
|
|
using ClassLibrary;
|
|
|
|
// Input: file ang.ini
|
|
// 1. If color is BLUE => create list of arcs depending of color value:
|
|
//254 0 360
|
|
//253 15 45 75 105 135 165 195 225 255 285 315 345
|
|
//252 0 75 105 180
|
|
//251 0 60 120 180
|
|
//250 0 45 135 180
|
|
//249 0 30 150 180
|
|
//248 0 15 165 180
|
|
// If BLUE color value is out of range => draw full circle (0-360) with radius defined by color GREEN
|
|
// and concentric value (draw one or multiple concentric arcs with delta R = step) defined by color RED
|
|
// 2. If color is GREEN => radius of arc = radiusMax*ColorValue/256; If value of GREEN == 0, then default radius = radiusMax
|
|
// 3. If color is RED => if ColorValue > 0 then draw concentric arcs with radius difference=step,
|
|
// in this case number of concentric arcs == Radius/Step (4.8/0.15 == 32 arcs).
|
|
|
|
namespace Treko
|
|
{
|
|
public class ColorArc
|
|
{
|
|
double _x;
|
|
double _y;
|
|
double _angleStart;
|
|
double _angleEnd;
|
|
double _sweepAngle;
|
|
double _sweepAngleAnimation = 1; // 1 degree for preview
|
|
double _angleStartRad;
|
|
double _angleEndRad;
|
|
double _radius1;
|
|
double _radius2;
|
|
double _maxRadius;
|
|
RectDouble _rect; // Small rectangle
|
|
RectDouble _rectCircumf; // Big circumference rectangle
|
|
int _mmToPixelsCoeff;
|
|
|
|
public int MmToPixelsCoeff
|
|
{
|
|
get { return _mmToPixelsCoeff; }
|
|
set { _mmToPixelsCoeff = value; }
|
|
}
|
|
|
|
public double X
|
|
{
|
|
get { return _x; }
|
|
set { _x = value; }
|
|
}
|
|
|
|
public double Y
|
|
{
|
|
get { return _y; }
|
|
set { _y = value; }
|
|
}
|
|
|
|
public double AngleStart
|
|
{
|
|
get { return _angleStart; }
|
|
set { _angleStart = value; }
|
|
}
|
|
|
|
public double AngleEnd
|
|
{
|
|
get { return _angleEnd; }
|
|
set { _angleEnd = value; }
|
|
}
|
|
|
|
public double AngleStartRad
|
|
{
|
|
get { return _angleStartRad; }
|
|
set { _angleStartRad = value; }
|
|
}
|
|
|
|
public double AngleEndRad
|
|
{
|
|
get { return _angleEndRad; }
|
|
set { _angleEndRad = value; }
|
|
}
|
|
|
|
public double SweepAngle
|
|
{
|
|
get { return _sweepAngle; }
|
|
set { _sweepAngle = value; }
|
|
}
|
|
|
|
public double Radius1
|
|
{
|
|
get { return _radius1; }
|
|
set { _radius1 = value; }
|
|
}
|
|
|
|
public double Radius2
|
|
{
|
|
get { return _radius2; }
|
|
set { _radius2 = value; }
|
|
}
|
|
|
|
public double MaxRadius
|
|
{
|
|
get { return _maxRadius; }
|
|
set { _maxRadius = value; }
|
|
}
|
|
|
|
public RectDouble Rect
|
|
{
|
|
get { return _rect; }
|
|
set { _rect = value; }
|
|
}
|
|
|
|
public RectDouble RectCircumf
|
|
{
|
|
get { return _rectCircumf; }
|
|
set { _rectCircumf = value; }
|
|
}
|
|
|
|
ColorArc()
|
|
{
|
|
|
|
}
|
|
|
|
public ColorArc(double startAngle, double endAngle)
|
|
{
|
|
//_x = x;
|
|
//_y = y;
|
|
_angleStart = startAngle;
|
|
_angleEnd = endAngle;
|
|
_sweepAngle = endAngle - startAngle;
|
|
_angleStartRad = _angleStart * Math.PI / 180;
|
|
_angleEndRad = _angleEnd * Math.PI / 180;
|
|
//_rect = CalcRectangleOfArc();
|
|
}
|
|
|
|
public ColorArc(double x, double y, double startAngle, double endAngle, double radius1, double radius2)
|
|
{
|
|
_x = x;
|
|
_y = y;
|
|
_angleStart = startAngle;
|
|
_angleEnd = endAngle;
|
|
_angleStartRad = _angleStart * Math.PI / 180;
|
|
_angleEndRad = _angleEnd * Math.PI / 180;
|
|
_sweepAngle = endAngle - startAngle;
|
|
_radius1 = radius1;
|
|
_radius2 = radius2;
|
|
_rect = CalcRectangleOfArc();
|
|
_rectCircumf = CalcCircumfRectangleOfArc();
|
|
}
|
|
|
|
// We have radius in mm
|
|
// The width of frame 0.2 mm or 1024 pixels
|
|
// So the size of radius in pixels Rpix = _radius*1024/0.2
|
|
// This is rectangle only for draw arc
|
|
public RectDouble CalcRectangleOfArc()
|
|
{
|
|
//_rect = new Rectangle(20, 20, 20, 20);
|
|
//return;
|
|
_rect = null;
|
|
if (_radius1 > 0)
|
|
{
|
|
// distances to point 0 of arc from center of arc segment
|
|
double dxStart = _radius1 * Math.Cos(_angleStartRad);
|
|
double dyStart = _radius1 * Math.Sin(_angleStartRad);
|
|
|
|
// distances to point 1 of arc from center of arc segment
|
|
double dxEnd = _radius1 * Math.Cos(_angleEndRad);
|
|
double dyEnd = _radius1 * Math.Sin(_angleEndRad);
|
|
|
|
// coordinates of point 0 of arc
|
|
double x0 = _x + dxStart;
|
|
double y0 = _y + dyStart;
|
|
|
|
// coordinates of point 1 of arc
|
|
double x1 = _x + dxEnd;
|
|
double y1 = _y + dyEnd;
|
|
|
|
if (x1 - x0 < 0)
|
|
{
|
|
x0 = _x + dxEnd;
|
|
x1 = _x + dxStart;
|
|
}
|
|
|
|
if (y1 - y0 < 0)
|
|
{
|
|
y0 = _y + dyEnd;
|
|
y1 = _y + dyStart;
|
|
}
|
|
|
|
_rect = new RectDouble(x0, y0, x1 - x0, y1 - y0); // !!!
|
|
//_rect = new Rectangle(10, 10, 20, 20);
|
|
}
|
|
|
|
return _rect;
|
|
}
|
|
|
|
// We have radius in mm
|
|
// The width of frame 0.2 mm or 1024 pixels
|
|
// So the size of radius in pixels Rpix = _radius*1024/0.2
|
|
// This is rectangle only for draw arc
|
|
public RectDouble CalcCircumfRectangleOfArc()
|
|
{
|
|
//_rect = new Rectangle(20, 20, 20, 20);
|
|
double x0, y0, width, height;
|
|
//return;
|
|
_rectCircumf = null;
|
|
if (_radius1 > 0)
|
|
{
|
|
x0 = _x - _radius1;
|
|
y0 = _y - _radius1;
|
|
|
|
width = 2 * _radius1;
|
|
height = 2 * _radius1;
|
|
if (width < 0)
|
|
x0 = 0;
|
|
|
|
_rectCircumf = new RectDouble(x0, y0, width, height); // !!!
|
|
//_rect = new Rectangle(10, 10, 20, 20);
|
|
}
|
|
|
|
return _rectCircumf;
|
|
}
|
|
|
|
//public bool DrawArcInFrame(RectDouble rect, Graphics g)
|
|
//{
|
|
// if (_radius1 != 0)
|
|
// {
|
|
// //Rect.DrawArcInFrame(rect, _rectCircumf, g, pen, _mmToPixelsCoeff, Convert.ToSingle(_angle - _sweepAngle / 2), Convert.ToSingle(_sweepAngle));
|
|
// //_rect.DrawGradationArcInFrame(rect, _rectCircumf, g, _mmToPixelsCoeff, Convert.ToSingle(_angle - _sweepAngle / 2), Convert.ToSingle(_sweepAngle));
|
|
// return true;
|
|
// }
|
|
// else
|
|
// return false;
|
|
//}
|
|
|
|
public bool DrawArcInFrame(RectDouble rect, Graphics g, int mmToPixelsCoeff, int[] profileColor)
|
|
{
|
|
if (_radius1 != 0)
|
|
{
|
|
//Rect.DrawArcInFrame(rect, _rectCircumf, g, pen, _mmToPixelsCoeff, Convert.ToSingle(_angle - _sweepAngle / 2), Convert.ToSingle(_sweepAngle));
|
|
RectCircumf.DrawGradationArcInFrame(rect, _rectCircumf, g, mmToPixelsCoeff, Convert.ToSingle(_angleStart), Convert.ToSingle(_sweepAngle), profileColor);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
public bool DrawArcByLine(Graphics g)
|
|
{
|
|
//int mmToPixelsCoeff = 50; // !!!
|
|
if (_radius1 != 0)
|
|
{
|
|
Pen pen = new Pen(Color.White, 1);
|
|
_rectCircumf.DrawArc(g, pen, _mmToPixelsCoeff, Convert.ToSingle(_angleStart), Convert.ToSingle(_angleEnd - _angleStart));
|
|
pen.Dispose();
|
|
//Rect.DrawGradationArc(g, _mmToPixelsCoeff, Convert.ToSingle(_angle - _sweepAngle/2), Convert.ToSingle(_sweepAngle));
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
public void DrawArc(Graphics g, int[] profileColor)
|
|
{
|
|
if (_radius1 != 0)
|
|
{
|
|
_rectCircumf.DrawGradationArc(g, Convert.ToSingle(_angleStart), Convert.ToSingle(_angleEnd - _angleStart), profileColor);
|
|
}
|
|
}
|
|
|
|
public void DrawAnimationArc(Graphics g, Pen penWhite, Pen penRed, Pen penBlue, int angPreview, int parallaxAng)
|
|
{
|
|
if (_radius1 != 0)
|
|
{
|
|
if (parallaxAng == 0)
|
|
{
|
|
if (angPreview >= _angleStart && angPreview <= _angleStart + _sweepAngle)
|
|
_rectCircumf.DrawArc(g, penWhite, _mmToPixelsCoeff, Convert.ToSingle(angPreview - _sweepAngleAnimation), Convert.ToSingle(_sweepAngleAnimation));
|
|
if (angPreview + 180 >= _angleStart && angPreview + 180 <= _angleStart + _sweepAngle)
|
|
_rectCircumf.DrawArc(g, penWhite, _mmToPixelsCoeff, Convert.ToSingle(angPreview + 180 - _sweepAngleAnimation), Convert.ToSingle(_sweepAngleAnimation));
|
|
}
|
|
else
|
|
{
|
|
if (angPreview >= _angleStart && angPreview <= _angleStart + _sweepAngle)
|
|
_rectCircumf.DrawArc(g, penRed, _mmToPixelsCoeff, Convert.ToSingle(angPreview - _sweepAngleAnimation), Convert.ToSingle(_sweepAngleAnimation));
|
|
if (angPreview + parallaxAng >= _angleStart - _sweepAngle && angPreview + parallaxAng <= _angleStart + _sweepAngle)
|
|
_rectCircumf.DrawArc(g, penBlue, _mmToPixelsCoeff, Convert.ToSingle(angPreview + parallaxAng - _sweepAngleAnimation), Convert.ToSingle(_sweepAngleAnimation));
|
|
if (angPreview +180 >= _angleStart && angPreview + 180 <= _angleStart + _sweepAngle)
|
|
_rectCircumf.DrawArc(g, penRed, _mmToPixelsCoeff, Convert.ToSingle(angPreview + 180 - _sweepAngleAnimation), Convert.ToSingle(_sweepAngleAnimation));
|
|
if (angPreview + parallaxAng + 180 >= _angleStart - _sweepAngle && angPreview + parallaxAng + 180 <= _angleStart + _sweepAngle)
|
|
_rectCircumf.DrawArc(g, penBlue, _mmToPixelsCoeff, Convert.ToSingle(angPreview + parallaxAng + 180 - _sweepAngleAnimation), Convert.ToSingle(_sweepAngleAnimation));
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
class BlueRecord
|
|
{
|
|
int _blueColorValue;
|
|
List<ColorArc> _arcs;
|
|
|
|
public int BlueColorValue
|
|
{
|
|
get { return _blueColorValue; }
|
|
set { _blueColorValue = value; }
|
|
}
|
|
|
|
public List<ColorArc> Arcs
|
|
{
|
|
get { return _arcs; }
|
|
set { _arcs = value; }
|
|
}
|
|
|
|
BlueRecord()
|
|
{
|
|
}
|
|
|
|
public BlueRecord(int colorValue, List<ColorArc> arcs)
|
|
{
|
|
_arcs = new List<ColorArc>();
|
|
_blueColorValue = colorValue;
|
|
_arcs = arcs;
|
|
}
|
|
|
|
public BlueRecord(int colorValue)
|
|
{
|
|
_arcs = new List<ColorArc>();
|
|
_blueColorValue = colorValue;
|
|
}
|
|
|
|
public void CreateColorArcs(string[] arcValues)
|
|
{
|
|
try
|
|
{
|
|
for (int i = 1; i < arcValues.Length; i += 2)
|
|
{
|
|
ColorArc colArc = new ColorArc(int.Parse(arcValues[i]), int.Parse(arcValues[i+1]));
|
|
_arcs.Add(colArc);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
public class Angles
|
|
{
|
|
string _path = "";
|
|
double _maxRadius;
|
|
double _step;
|
|
|
|
List<BlueRecord> _blueRecords;
|
|
ColorPixel _result;
|
|
|
|
public string Path
|
|
{
|
|
get { return _path; }
|
|
set { _path = value; }
|
|
}
|
|
|
|
public double MaxRadius
|
|
{
|
|
get { return _maxRadius; }
|
|
set { _maxRadius = value; }
|
|
}
|
|
|
|
public double Step
|
|
{
|
|
get { return _step; }
|
|
set { _step = value; }
|
|
}
|
|
|
|
Angles()
|
|
{
|
|
|
|
}
|
|
|
|
public Angles(string path)
|
|
{
|
|
_path = path;
|
|
_blueRecords = new List<BlueRecord>();
|
|
|
|
string[] lines = File.ReadAllLines(path);
|
|
|
|
foreach (string line in lines)
|
|
{
|
|
string[] items = line.Split(' ');
|
|
BlueRecord blueRec = new BlueRecord(int.Parse(items[0]));
|
|
blueRec.CreateColorArcs(items);
|
|
_blueRecords.Add(blueRec);
|
|
}
|
|
}
|
|
|
|
private List<ColorArc> createDefaultArc(double x, double y, int greenValue)
|
|
{
|
|
List<ColorArc> arcs = new List<ColorArc>();
|
|
|
|
double radius = MaxRadius;
|
|
|
|
if (greenValue > 0)
|
|
{
|
|
radius = MaxRadius * greenValue / 256;
|
|
}
|
|
|
|
ColorArc colArc = new ColorArc(x, y, 0, 360, radius, radius);
|
|
|
|
//colArc.Radius1 = radius;
|
|
//colArc.Radius2 = radius;
|
|
|
|
arcs.Add(colArc);
|
|
|
|
return arcs;
|
|
}
|
|
|
|
private void fillRadiusInArcs(double x, double y, List<ColorArc> arcs, int greenValue)
|
|
{
|
|
double radius = MaxRadius;
|
|
foreach (ColorArc colArc in arcs)
|
|
{
|
|
if (greenValue > 0)
|
|
radius = MaxRadius * greenValue / 256;
|
|
|
|
colArc.Radius1 = radius;
|
|
colArc.Radius2 = radius;
|
|
|
|
colArc.X = x;
|
|
colArc.Y = y;
|
|
|
|
colArc.CalcRectangleOfArc();
|
|
colArc.CalcCircumfRectangleOfArc();
|
|
}
|
|
}
|
|
|
|
// If color.R > 0 and arcs.Count > 1, then create concentric set of arcs
|
|
// if color.G != 0 radius = MaxRadius * color.G / 256; else radius = MaxRadius;
|
|
// For each next arc radius = radius - step
|
|
private void addConcentricArcs(double x, double y, List<ColorArc> arcs, Color color)
|
|
{
|
|
List<ColorArc> arcs1 = new List<ColorArc>();
|
|
|
|
foreach (ColorArc arc in arcs)
|
|
{
|
|
double radius = arc.Radius1;
|
|
int nRadsToAdd = Convert.ToInt16(radius / _step);
|
|
for (int i = 1; i < nRadsToAdd; i++)
|
|
{
|
|
radius -= _step;
|
|
ColorArc colArc = new ColorArc(x, y, arc.AngleStart, arc.AngleEnd, radius, radius);
|
|
arcs1.Add(colArc);
|
|
}
|
|
}
|
|
|
|
if (arcs1.Count > 0)
|
|
arcs.AddRange(arcs1);
|
|
}
|
|
|
|
private List<ColorArc> CopyRange(List<ColorArc> colorArcs)
|
|
{
|
|
List<ColorArc> arcs = null;
|
|
if (colorArcs != null && colorArcs.Count > 0)
|
|
{
|
|
arcs = new List<ColorArc>();
|
|
foreach (ColorArc arc in colorArcs)
|
|
{
|
|
ColorArc newArc = new ColorArc(arc.AngleStart, arc.AngleEnd);
|
|
arcs.Add(newArc);
|
|
}
|
|
}
|
|
|
|
return arcs;
|
|
}
|
|
|
|
private List<ColorArc> getArcs(double x, double y, Color color)
|
|
{
|
|
List<ColorArc> arcs = null;
|
|
foreach (BlueRecord rec in _blueRecords)
|
|
{
|
|
if (rec.BlueColorValue == color.B)
|
|
{
|
|
arcs = CopyRange(rec.Arcs);
|
|
break;
|
|
}
|
|
}
|
|
// if there is no arcs for value, then create default arc
|
|
// if GreenValue != 0 radius = MaxRadius * greenValue / 256; else radius = MaxRadius;
|
|
// and angles from 0 to 360
|
|
if (arcs == null)
|
|
arcs = createDefaultArc(x, y, color.G);
|
|
else
|
|
fillRadiusInArcs(x, y, arcs, color.G);
|
|
|
|
// If we have list of arcs and Red value > 0 then
|
|
// create concentric set of arcs with delta-radius == step
|
|
if (color.R > 0)
|
|
addConcentricArcs(x, y, arcs, color);
|
|
|
|
return arcs;
|
|
}
|
|
|
|
// Arcs constructor
|
|
// input: color value from input image
|
|
// output: arc or list of arcs, generated using ANG.INI file
|
|
public ColorPixel CreateColorPixel(Color color, double x, double y, double maxRadius, double step)
|
|
{
|
|
ColorArc[] arcsArr;
|
|
|
|
_maxRadius = maxRadius;
|
|
_step = step;
|
|
|
|
// color.B => arcs list from ANG.INI file
|
|
List<ColorArc> arcs = getArcs(x, y, color);
|
|
arcsArr = arcs.ToArray();
|
|
|
|
ColorPixel colPix = new ColorPixel(arcsArr, x, y);
|
|
return colPix;
|
|
}
|
|
|
|
}
|
|
}
|