All your questions from post #1 were answered, do you still have questions ?
I am completey stuck I am afraid.
I followed this explanation of Bezier curves (
https://medium.freecodecamp.org/nerding-out-with-bezier-curves-6e3c0bc48e2f) and I had a quite good understanding of it by the end. I get the B(t)x and B(t)y forumulas for deriving the line segments that make up the curve.
I am reading my control points from a DFX file and here are a couple of sample splines from the DFX file below.
'10' followed by a floating point value is the 'X' axis, '20' followed by a floating point value is the 'Y' axis and '30' followed by a floating point number is the 'Z' axis. Z axis is always 0 since it is a 2 dimensional PCB design.
And there always seems to be 4 control points for all the splines in the DFX file.
However my code has incomplete provision for splines with greater than 4 control points, for what it was worth.
The rest of the 'SPLINE' details seem to be fairly irrelevant for a 2D PCB design. For example '72' followed by 8 tells you that the spline as 8 x knots. '40' followed by an integer tells you the value of each of the 8 x knots. These are always 1 or 0. I have read that 'knots' are the same thing as 'control points'. So I have no idea what purpose 'knots' serve in this particular DFX file.
'73' followed by '4' tells you that there are 4 control points and there are indeed 4 x sets of floating point x,y,z coordinates for each SPLINE in the sample DFX contents. So this is the only important information about the SPLINES in this particular DFX file.
Code:
SPLINE
5
4E
100
AcDbEntity
8
Layer_1
6
ByLayer
62
7
370
-1
100
AcDbSpline
210
0
220
0
230
0
70
8
71
3
72
8
73
4
74
0
42
1e-007
43
1e-007
40
0
40
0
40
0
40
0
40
1
40
1
40
1
40
1
10
66.89290099999999
20
0.159256
30
0
10
66.58310299999999
20
0.28965
30
0
10
66.055547
20
0.611722
30
0
10
65.72051999999999
20
0.875231
30
0
0
SPLINE
5
4F
100
AcDbEntity
8
Layer_1
6
ByLayer
62
7
370
-1
100
AcDbSpline
210
0
220
0
230
0
70
8
71
3
72
8
73
4
74
0
42
1e-007
43
1e-007
40
0
40
0
40
0
40
0
40
1
40
1
40
1
40
1
10
65.72051999999999
20
0.875231
30
0
10
65.124989
20
1.343684
30
0
10
64.73791799999999
20
1.354371
30
0
10
48.357153
20
1.354371
30
0
0
This is my code for calculating the line segments that form a curve defined by 4 x control points contained in 'arrayCtrlPnts'.
nSplineType always seems to be 8, for planar spline, and nSplineDegree always seems to be 3.
Assume that the remainder of my code is only concerned with extracting the SPLINE control points from the file.
I have tested this thoroughly and I am definitely getting the correct floating point values in each element of arrayCtrlPnts - parameter of function BezierCurve(...)
Code:
class CFloatPoint
{
public:
CFloatPoint();
CFloatPoint(CFloatPoint& point);
virtual ~CFloatPoint();
CFloatPoint &operator =(CFloatPoint &point);
operator CPoint&()
{
static CPoint point;
point.x = (int)round(m_fX);
point.y = (int)round(m_fY);
return point;
};
float m_fX, m_fY;
};
float cube(const float fVal)
{
return fVal * fVal * fVal;
}
float square(const float fVal)
{
return fVal * fVal;
}
// CFloatPointArray is defined as typedef CArray<CFloatPoint, CFloatPoint&> CFloatPointArray
// CArray is one of the MFC template collection classes.
// CArray objects are used much like a regular CArray except that they are dynamic without requiring you to implement all the memory
// allocation and deallocation.
// You index them like a regular C array but you can add elements to the end via CArray::Add(...).
// CStringArray is defined as typedef CArray<CString, LPCSTR> CStringArray;
// This array is filled by function BezierCurve(...) with simple text instructions that I transmit over UDP serial to my Arduino based CNC engraver.
// "MT" means 'move to' and it is followed by an x,y coordinate.
// "LT" means 'line to' and it is followed by an x,y coordinate as well as a percentage density which used to PWM the laser. I have envisaged using the laser
// engraver to engrave images as well as PCBs.
// I am then using this array of Arduino instructions to render the PCB design in the windows app.
void CGregsLaserEngraverDlg::BezierCurve(const byte nSplineType, const byte nSplineDegree, CFloatPointArray &arrayCtrlPnts, CStringArray &arrayFormatted)
{
if (nSplineType == 8/*Planar spline*/)
{
if (nSplineDegree == 3 /*Cubic spline*/)
{
CFloatPoint point;
CString strCode;
strCode.Format("MT,%f,%f", arrayCtrlPnts[0].m_fX, arrayCtrlPnts[0].m_fY);
arrayFormatted.Add(strCode);
// For both X and Y
// B(t) = (1-t)^3P0 + 3(1-t)^2tP1 + 3(1-t)t^2P2 + t^3P3
for (float fT = 0; fT < 1.0f; fT += 0.1f)
{
point.m_fX = (cube(1.0f - fT) * arrayCtrlPnts[0].m_fX) + (3 * square(1.0f - fT) * arrayCtrlPnts[1].m_fX) + (3 * (1.0f - fT) * square(fT) * arrayCtrlPnts[2].m_fX) + (cube(fT) * arrayCtrlPnts[3].m_fX);
point.m_fY = (cube(1.0f - fT) * arrayCtrlPnts[0].m_fY) + (3 * square(1.0f - fT) * arrayCtrlPnts[1].m_fY) + (3 * (1.0f - fT) * square(fT) * arrayCtrlPnts[2].m_fY) + (cube(fT) * arrayCtrlPnts[3].m_fY);
strCode.Format("LT,%f,%f,100", point.m_fX, point.m_fY);
arrayFormatted.Add(strCode);
}
}
else
{
AfxMessageBox("Spline degree not implemented", MB_OK);
}
}
else
{
AfxMessageBox("Spline type not implemented", MB_OK);
}
}
This is what I get when I try to draw all the individual lines:
There are actually valid PCB trace outlines buried under all that.
The correct outlines come from 'POLYLINES' that are also in the DFX file.
But clearly I am doing somethign fundamentally wrong with the way I am calculating the line segments in the 'SPLINE' curves.
But I don't understand what I am doing wrong.
I don't see any value in pasting the rest of my code in here as it is all irrelevant windows stuff and DFX file stuff.
I don't need help in interperting what all the contents of the DFX file.
And the forum won't let me attach other than valid image files anyway.
- - - Updated - - -
I don't have to do any calculation with 'POLYLINES' - the coordinates are just read from file and draw.