It's okay at school, so I developed a two-dimensional CAD with basic functions, with draw lines, draw rectangles, draw circles, pick up and select, translate, rotate, mirror, delete, zoom in and out in real time, serializing Functions
First, let's talk about the architecture. The architecture adopts the popular MVC Architecture, that is, the model, view, and controller. The model includes data and operations on data, while the view displays the model, the controller operates according to the interface.
(1) to facilitate development, we first developed two mathematical tool classes for ease of use.
Point class and box class
Class cbox2d;
Class cposition
{
Public:
Cposition ();
Cposition (float X, float y );
Virtual ~ Cposition ();
Public:
Float verdistance (cposition & begin, cposition & End );
Float distance (const cposition POS );
Bool isbox (const cbox2d & POX );
Cposition rotate (const cposition & base, float angle );
Cposition explan (const cposition & base, float scale );
Cposition mirror (cposition & first, cposition & second );
Cposition move (cposition & first, cposition & second );
Float aagletox ();
Void get2point (double circel [2]);
Cposition operator-(cposition POS );
Cposition operator + (cposition POS );
Void operator-= (cposition POS );
Void operator + = (cposition POS );
Cposition operator * (float scale );
PRIVATE:
Float m_x;
Float m_y;
};
Class cbox2d
{
Public:
Cbox2d ();
Cbox2d (cposition min, cposition max );
Virtual ~ Cbox2d ();
Public:
Void getexbox2d (float distance); // expanded perimeter
PRIVATE:
Cposition m_min;
Cposition m_max;
};
The implementation of the two classes is as follows:
# Define IP 3.1415926
//////////////////////////////////////// //////////////////////////////
// Construction/destruction
//////////////////////////////////////// //////////////////////////////
Cbox2d: cbox2d ()
{
}
Cbox2d ::~ Cbox2d ()
{
}
Cbox2d: cbox2d (cposition min, cposition max)
{
M_min = min;
M_max = max;
}
Void cbox2d: getexbox2d (float distance) // expanded box. When the straight line is horizontal or vertical, there is no box surrounded, so it is necessary to enclose the diagonal point translation to adapt to this situation.
{
M_min.m_x-= distance;
M_min.m_y-= distance;
M_max.m_x + = distance;
M_max.m_y + = distance;
}
Cposition: cposition ()
{
}
Cposition: cposition (float X, float y)
{
M_x = X;
M_y = y;
}
Cposition ::~ Cposition ()
{
}
Float cposition: verdistance (cposition & begin, cposition & End) // calculate two-dimensional distance using a three-dimensional cross set. The zcoordinate is 0.
{
Float a = fabsf (m_x-begin. m_x) * (end. m_y-begin. m_y)-(m_y-begin. m_y) * (end. m_x-begin. m_x ));
Float B = SQRT (end. m_x-begin. m_x) * (end. m_x-begin. m_x) + (end. m_y-begin. m_y) * (end. m_y-begin. m_y ));
Return A/B;
}
Bool cposition: isbox (const cbox2d & POX)
{
If (m_x> = pox. m_min.m_x & m_y> = pox. m_min.m_y & m_x <= pox. m_max.m_x & m_y <= pox. m_max.m_y)
Return true;
Else
Return false;
}
Cposition: Rotate (const cposition & base, float angle) // rotate the angle degree along a point, which is positive counterclockwise.
{
Float x = (m_x-base. m_x) * Cos (angle)-(m_y-base. m_y) * sin (angle) + base. m_x;
Float y = (m_x-base. m_x) * sin (angle) + (m_y-base. m_y) * Cos (angle) + base. m_y;
Return cposition (x, y );
}
Cposition: Explain (const cposition & base, float scale)
{
* This = (* This-base) * scale + base;
Return * this;
}
Cposition: Move (cposition & first, cposition & Second) // pan along two points
{
Cposition Pos;
Pos = Second-first;
* This + = Pos;
Return * this;
}
Cposition: Operator-(cposition POS)
{
Return cposition (m_x-pos. m_x, m_y-pos. m_y );
}
Cposition: Operator + (cposition POS)
{
Return cposition (m_x + pos. m_x, m_y + pos. m_y );
}
Void cposition: Operator-= (cposition POS)
{
M_x-= pos. m_x;
M_y-= pos. m_y;
}
Void cposition: Operator + = (cposition POS)
{
M_x + = pos. m_x;
M_y + = pos. m_y;
}
Float cposition: distance (const cposition POS)
{
Return SQRT (m_x-pos. m_x) * (m_x-pos. m_x) + (m_y-pos. m_y) * (m_y-pos. m_y ));
}
Float cposition: aagletox ()//
{
Float COSV = m_x/SQRT (m_x * m_x + m_y * m_y );
Float SINV = m_y/SQRT (m_x * m_x + m_y * m_y );
If (SINV> = 0)
Return ACOs (COSV );
Else if (SINV <0)
Return 2. * IP-ACOs (COSV );
Return false;
}
Cposition: Operator * (float scale)
{
Return cposition (m_x * scale, m_y * scale );
}
Cposition: Mirror (cposition & first, cposition & Second)
{
Cposition Pos = (second-first) * (1/second. Distance (first); // image line unitization
Cposition pos1 = * This-first; // vector between the first starting point and the image point
Float pos2 = pos1.m _ x * pos. m_x + pos1.m _ y * pos. m_y;
Return (first + POS * pos2) * 2-* this;
}
The coordinates of the world, that is, the coordinates of the objects we actually see in reality.
Customer coordinates, that is, the coordinates of the customer area on our screen
The coordinates of all our points must be converted between these two coordinates.
These two functions can be placed in the derived class of cview.
For example
Void cmcadview: dptowp (cpoint & point, cposition & Pos) // m_base_x, m_base_y: observes the base point coordinate of the coordinate system. m_scale is the observation coordinate and the coefficient of customer transformation.
{
Crect rect;
Getclientrect (& rect );
POs. m_x = point. x * m_scale + m_base_x;
POs. m_y = (rect. Height ()-point. Y) * m_scale + m_base_y;
}
Void cmcadview: wptodp (cposition & Pos, cpoint & point)
{
Crect rect;
Getclientrect (& rect );
Point. x = (INT) (Pos. m_x-m_base_x)/m_scale;
Point. Y = rect. Height ()-(INT) (Pos. m_y-m_base_y)/m_scale;
}
All mouse operations on the screen must be converted to actual coordinates using these two functions, and all the actual coordinates displayed on the screen must be converted
Screen coordinates