using System;
using System .Collections .Generic;
using System .ComponentModel;
using System .Drawing;
using System .Drawing .Drawing2D;
using System .Windows .Forms;
using MoveGraphLibrary;
namespace GraphicalPrimitives
{
public class Plug : GraphicalObject
{
int m_version = 620;
Form form;
Mover supervisor;
Shape m_shape;
PointF m_center;
float m_radius;
int nVertices;
double m_angle;
SolidBrush m_brush;
PointF ptInnerLimit, ptOuterLimit;
double scaling, compensation, rMouse;
static float minRadius = 10;
int minDelta = 3;
// -------------------------------------------------
public Plug (Form frm, Mover mvr, PointF pt, float rad, Color clr)
{
form = frm;
supervisor = mvr;
m_shape = Shape .Circle;
m_center = pt;
m_radius = Math .Max (minRadius, rad);
nVertices = 0;
m_angle = 0;
m_brush = new SolidBrush (clr);
}
// -------------------------------------------------
public Plug (Form frm, Mover mvr, PointF pt, float rad, int nPoints, double angleDegree, Color clr)
{
switch (nPoints)
{
case 3:
default:
m_shape = Shape .Polyg_3;
nVertices = 3;
break;
case 4:
m_shape = Shape .Polyg_4;
nVertices = 4;
break;
case 5:
m_shape = Shape .Polyg_5;
nVertices = 5;
break;
case 6:
m_shape = Shape .Polyg_6;
nVertices = 6;
break;
case 7:
m_shape = Shape .Polyg_7;
nVertices = 7;
break;
case 8:
m_shape = Shape .Polyg_8;
nVertices = 8;
break;
}
form = frm;
supervisor = mvr;
m_center = pt;
m_radius = Math .Max (minRadius, rad);
nVertices = Math .Max (3, nPoints);
m_angle = Auxi_Convert .DegreeToRadian (angleDegree);
m_brush = new SolidBrush (clr);
}
// ------------------------------------------------- Shape
public Shape Shape
{
get { return (m_shape); }
}
// ------------------------------------------------- RectAround
new public RectangleF RectAround
{
get
{
if (m_shape == Shape .Circle)
{
return (RectangleF .FromLTRB (m_center .X - m_radius, m_center .Y - m_radius, m_center .X + m_radius, m_center .Y + m_radius));
}
else
{
return (Auxi_Geometry .RectAroundPoints (Vertices));
}
}
}
// ------------------------------------------------- Center
public PointF Center
{
get { return (m_center); }
//set { m_center = value; }
}
// ------------------------------------------------- Radius
public float Radius
{
get { return (m_radius); }
}
// ------------------------------------------------- MinimumRadius
static public float MinimumRadius
{
get { return (minRadius); }
}
// ------------------------------------------------- VerticesNumber
public int VerticesNumber
{
get { return (nVertices); }
}
// ------------------------------------------------- Angle
public double Angle
{
get { return (m_angle); }
}
// ------------------------------------------------- Vertices
public PointF [] Vertices
{
get { return ((m_shape == Shape .Circle) ? null : Auxi_Geometry .RegularPolygon (m_center, m_radius, nVertices, m_angle)); }
}
// ------------------------------------------------- Draw
public void Draw (Graphics grfx)
{
if (m_shape == Shape .Circle)
{
Auxi_Drawing .FillEllipse (grfx, m_center, Convert .ToInt32 (m_radius), m_brush .Color);
}
else
{
grfx .FillPolygon (m_brush, Vertices);
}
}
// ------------------------------------------------- StartResizing
public void StartResizing (Point ptMouse)
{
PointF ptCursor;
double angleBeam;
if (m_shape == Shape .Circle)
{
angleBeam = Auxi_Geometry .Line_Angle (m_center, ptMouse);
ptCursor = Auxi_Geometry .PointToPoint (m_center, angleBeam, m_radius);
ptInnerLimit = Auxi_Geometry .PointToPoint (m_center, angleBeam, minRadius);
}
else
{
PointF [] pts = Vertices;
Auxi_Geometry .Distance_PointPolyline (ptMouse, pts, true, out ptCursor);
scaling = m_radius / Auxi_Geometry .Distance (m_center, ptCursor); // >= 1
angleBeam = Auxi_Geometry .Line_Angle (m_center, ptCursor);
ptInnerLimit = Auxi_Geometry .PointToPoint (m_center, angleBeam, minRadius / scaling);
}
ptOuterLimit = Auxi_Geometry .PointToPoint (m_center, angleBeam, 4000);
Cursor .Position = form .PointToScreen (Point .Round (ptCursor));
}
// ------------------------------------------------- StartRotation
public void StartRotation (Point ptMouse)
{
double angleMouse = Auxi_Geometry .Line_Angle (m_center, ptMouse);
compensation = Auxi_Common .LimitedRadian (angleMouse - Angle);
rMouse = Auxi_Geometry .Distance (m_center, ptMouse);
}
// ------------------------------------------------- DefineCover
public override void DefineCover ()
{
CoverNode [] nodes = new CoverNode [2];
if (m_shape == Shape .Circle)
{
nodes [0] = new CoverNode (0, m_center, m_radius - minDelta, Cursors .SizeAll);
nodes [1] = new CoverNode (1, m_center, m_radius + minDelta);
}
else
{
double delta = minDelta / Math .Cos (Math .PI / nVertices);
PointF [] ptsInside = Auxi_Geometry .RegularPolygon (m_center, m_radius - delta, nVertices, m_angle);
PointF [] ptsOutside = Auxi_Geometry .RegularPolygon (m_center, m_radius + delta, nVertices, m_angle);
nodes [0] = new CoverNode (0, ptsInside);
nodes [1] = new CoverNode (1, ptsOutside, Cursors .Hand);
}
cover = new Cover (nodes);
}
// -------------------------------------------------
public override void Move (int dx, int dy)
{
m_center += new Size (dx, dy);
}
// ------------------------------------------------- MoveNode
public override bool MoveNode (int i, int dx, int dy, Point ptM, MouseButtons catcher)
{
bool bRet = false;
if (catcher == MouseButtons .Left)
{
if (i == 0)
{
Move (dx, dy);
}
else
{
PointF ptBase, ptNearest;
PointOfSegment typeOfNearest;
Auxi_Geometry .Distance_PointSegment (ptM, ptInnerLimit, ptOuterLimit, out ptBase, out typeOfNearest, out ptNearest);
double dist = Auxi_Geometry .Distance (m_center, ptNearest);
if (m_shape == Shape .Circle)
{
m_radius = Convert .ToSingle (dist);
}
else
{
m_radius = Convert .ToSingle (dist * scaling);
}
bRet = true;
Cursor .Position = form .PointToScreen (Point .Round (ptNearest));
}
}
else if (catcher == MouseButtons .Right)
{
double angleMouse = Auxi_Geometry .Line_Angle (m_center, ptM);
m_angle = angleMouse - compensation;
Cursor .Position = form .PointToScreen (Point .Round (Auxi_Geometry .PointToPoint (m_center, angleMouse, rMouse)));
bRet = true;
}
return (bRet);
}
}
}