Loading pcbnew/class_teardrop.cpp +81 −48 Original line number Original line Diff line number Diff line Loading @@ -3,6 +3,7 @@ #include "class_board_item.h" #include "class_board_item.h" #include "class_undoredo_container.h" #include "class_undoredo_container.h" #include "geometry/seg.h" #include "geometry/seg.h" #include "geometry/shape_circle.h" #include "router/pns_utils.h" #include "router/pns_utils.h" TEARDROP::TEARDROP() TEARDROP::TEARDROP() Loading Loading @@ -36,22 +37,15 @@ bool TEARDROP::Create(TRACK &aTrack, ENDPOINT_T endPoint, TEARDROP_TYPE type = T } } if (type == TEARDROP_STRAIGHT) { if (type == TEARDROP_STRAIGHT) { result = StraightSegments(aTrack, *aVia, m_upperSegment, m_lowerSegment, 100); result = StraightSegments(aTrack, *aVia, 100); } } else if (type == TEARDROP_CURVED) { else if (type == TEARDROP_CURVED) { result = CurvedSegments(aTrack, *aVia, m_upperSegment, m_lowerSegment); result = CurvedSegments(aTrack, *aVia); } } return result; return result; } } void TEARDROP::GetCoordinates(std::vector<VECTOR2I> &points) { // points.insert(points.end(), m_upperSegment.begin(), m_upperSegment.end()); // points.insert(points.end(), m_lowerSegment.begin(), m_lowerSegment.end()); points = vect; } bool TEARDROP::SetVector(TRACK &aTrack, const VIA & aVia, VECTOR2I &startPoint, VECTOR2I &endPoint) bool TEARDROP::SetVector(TRACK &aTrack, const VIA & aVia, VECTOR2I &startPoint, VECTOR2I &endPoint) { { // Decide which end of the track is inside via and set this point as end of vector // Decide which end of the track is inside via and set this point as end of vector Loading @@ -72,10 +66,12 @@ bool TEARDROP::SetVector(TRACK &aTrack, const VIA & aVia, VECTOR2I &startPoint, return true; return true; } } bool TEARDROP::CurvedSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECTOR2I> &upperSegment, std::vector<VECTOR2I> &lowerSegment) bool TEARDROP::CurvedSegments(TRACK &aTrack, const VIA &aVia) { { VECTOR2I startPoint(0, 0); VECTOR2I startPoint(0, 0); VECTOR2I endPoint(0, 0); VECTOR2I endPoint(0, 0); std::vector<VECTOR2I> upperSegment; std::vector<VECTOR2I> lowerSegment; if ( !SetVector(aTrack, aVia, startPoint, endPoint) ) { if ( !SetVector(aTrack, aVia, startPoint, endPoint) ) { return false; return false; Loading @@ -90,29 +86,76 @@ bool TEARDROP::CurvedSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECTOR VECTOR2I point(0, 0); VECTOR2I point(0, 0); VECTOR2I viaCenter(aVia.GetPosition().x, aVia.GetPosition().y); VECTOR2I viaCenter(aVia.GetPosition().x, aVia.GetPosition().y); double coeff = M_PI / 180.0; VECTOR2I apertureUpper(0, 0); VECTOR2I apertureLower(0, 0); double radius = (aVia.GetWidth() / 2) - (aTrack.GetWidth() / 2); double radius = (aVia.GetWidth() / 2) - (aTrack.GetWidth() / 2); double rotationAngle = VECTOR2I(startPoint - endPoint).Angle(); double rotationAngle = VECTOR2I(startPoint - endPoint).Angle(); // Calculate segments of deltoid // Calculate the segments of deltoid composing the outline of a teardrop for ( int i = 10; i <= 60; i = i + 10 ) { for ( int i = 10; i <= 60; i = i + 10 ) { point.x = 2 * radius * cos(coeff * i) + radius * cos(2 * coeff * i); PointOnCurve(i, radius, point); point.y = 2 * radius * sin(coeff * i) - radius * sin(2 * coeff * i); point = point.Rotate(rotationAngle); point = point.Rotate(rotationAngle); point += viaCenter; point += viaCenter; upperSegment.push_back(point); m_coordinates.push_back(point); if (i == 50) { apertureUpper = point; } } } for ( int i = 300; i <= 350; i = i + 10 ) { for ( int i = 300; i <= 350; i = i + 10 ) { point.x = 2 * radius * cos(coeff * i) + radius * cos(2 * coeff * i); PointOnCurve(i, radius, point); point.y = 2 * radius * sin(coeff * i) - radius * sin(2 * coeff * i); point = point.Rotate(rotationAngle); point += viaCenter; m_coordinates.push_back(point); if (i == 340) { apertureLower = point; } } // Calculate the number of segments needed to fill the area inside the teardrop if (aVia.GetWidth() / 2 > 2 * aTrack.GetWidth()) { // First, calculate the distance between two points on both sides of the track and // number of iterations required to fill the zone SEG aperture(apertureUpper, apertureLower); int numSegments = aperture.Length() / aTrack.GetWidth(); int delta = radius / numSegments; for (int iteration = 0; iteration < numSegments; iteration++) { radius = radius - delta; for ( int i = 10; i <= 60; i = i + 10 ) { PointOnCurve(i, radius, point); point = point.Rotate(rotationAngle); point += viaCenter; if (i == 10) { int distance = SEG(viaCenter, point).Length(); if (distance < aVia.GetWidth() / 2) { break; } } m_coordinates.push_back(point); } lowerSegment.clear(); for ( int i = 350; i >= 300; i = i - 10 ) { PointOnCurve(i, radius, point); point = point.Rotate(rotationAngle); point = point.Rotate(rotationAngle); point += viaCenter; point += viaCenter; if (i == 350) { int distance = SEG(viaCenter, point).Length(); if (distance < aVia.GetWidth() / 2) { break; } } lowerSegment.push_back(point); lowerSegment.push_back(point); } } // Revert coordinates order for (std::vector<VECTOR2I>::reverse_iterator iter = lowerSegment.rbegin(); iter != lowerSegment.rend(); ++iter) { m_coordinates.push_back(*iter); } } } return true; return true; } } bool TEARDROP::StraightSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECTOR2I> &upperSegment, std::vector<VECTOR2I> &lowerSegment, int distance = 100) bool TEARDROP::StraightSegments(TRACK &aTrack, const VIA &aVia, int distance = 100) { { VECTOR2I startPoint(0, 0); VECTOR2I startPoint(0, 0); VECTOR2I endPoint(0, 0); VECTOR2I endPoint(0, 0); Loading Loading @@ -154,12 +197,8 @@ bool TEARDROP::StraightSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECT upperPoint += viaCenter; upperPoint += viaCenter; lowerPoint += viaCenter; lowerPoint += viaCenter; upperSegment.push_back(linePoint); upperSegment.push_back(upperPoint); // Calculate the number of segments needed to fill the area inside the teardrop // Calculate the number of segments needed to fill the area inside the teardrop std::vector<VECTOR2I> splitPoints; std::vector<VECTOR2I> splitPoints; int vertexNum = 1; if (aVia.GetWidth() / 2 > 2 * aTrack.GetWidth()) { if (aVia.GetWidth() / 2 > 2 * aTrack.GetWidth()) { // First, calculate the intersection point of the circle and one hand of the teardrop // First, calculate the intersection point of the circle and one hand of the teardrop r = aVia.GetWidth() / 2; r = aVia.GetWidth() / 2; Loading @@ -170,60 +209,54 @@ bool TEARDROP::StraightSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECT x = (upperPoint.x - startPoint.x) * t + startPoint.x; x = (upperPoint.x - startPoint.x) * t + startPoint.x; y = (upperPoint.y - startPoint.y) * t + startPoint.y; y = (upperPoint.y - startPoint.y) * t + startPoint.y; VECTOR2I intersectionPoint((int)x, (int)y); VECTOR2I intersectionPoint((int)x, (int)y); DrawDebugPoint(intersectionPoint, 5); // Second, calculate the distance between the track given and the intersection point // Second, calculate the distance between the given track and the intersection point SEG trackSegment(aTrack.GetStart().x, aTrack.GetStart().y, aTrack.GetEnd().x, aTrack.GetEnd().y); SEG trackSegment(aTrack.GetStart().x, aTrack.GetStart().y, aTrack.GetEnd().x, aTrack.GetEnd().y); int dist = trackSegment.LineDistance(intersectionPoint); int dist = trackSegment.LineDistance(intersectionPoint); int numSegments = 2 * dist / aTrack.GetWidth(); int numSegments = 2 * dist / aTrack.GetWidth(); // Third, subdivide radius of the via and build additional segments // Third, subdivide the diameter of the via and build additional segments SEG segRadius = SEG(upperPoint, lowerPoint); SEG segDiameter = SEG(upperPoint, lowerPoint); // SEG segRadius = SEG(upperPoint, viaCenter); SplitSegment(segDiameter, numSegments, splitPoints); SplitSegment(segRadius, numSegments, splitPoints); } } std::list<VECTOR2I> pts; std::list<VECTOR2I> outlinePoints; pts.push_back(upperPoint); outlinePoints.push_back(upperPoint); for (size_t i = 0; i < splitPoints.size(); i++) { for (size_t i = 0; i < splitPoints.size(); i++) { pts.push_back(splitPoints[i]); outlinePoints.push_back(splitPoints[i]); } } pts.push_back(lowerPoint); outlinePoints.push_back(lowerPoint); vertexNum = 0; // Biuld triangles filling the teardrop std::list<VECTOR2I>::iterator iter = pts.begin(); int vertexNum = 0; while ( iter != pts.end() ) { std::list<VECTOR2I>::iterator iter = outlinePoints.begin(); while ( iter != outlinePoints.end() ) { switch (vertexNum) { switch (vertexNum) { case 0: case 0: vect.push_back(linePoint); m_coordinates.push_back(linePoint); vertexNum++; vertexNum++; break; break; case 1: case 1: vect.push_back(*iter); m_coordinates.push_back(*iter); vertexNum++; vertexNum++; iter++; iter++; break; break; case 2: case 2: vect.push_back(*iter); m_coordinates.push_back(*iter); vertexNum = 0; vertexNum = 0; iter++; iter++; break; break; default:break; default:break; } } } } // Append additional vertexies in order to finish last triangle if (vertexNum == 0) { if (vertexNum == 0) { vect.push_back(linePoint); m_coordinates.push_back(linePoint); } } else if (vertexNum == 2) { else if (vertexNum == 2) { vect.push_back(vect[vect.size() - 3]); m_coordinates.push_back(m_coordinates[m_coordinates.size() - 3]); vect.push_back(linePoint); m_coordinates.push_back(linePoint); } for (size_t i = 0; i < vect.size(); i++) { printf("%d, %d\n", vect[i].x, vect[i].y); } } // lowerSegment.push_back(lowerPoint); // lowerSegment.push_back(linePoint); return true; return true; } } Loading pcbnew/class_teardrop.h +9 −8 Original line number Original line Diff line number Diff line Loading @@ -55,7 +55,7 @@ public: */ */ bool Create(TRACK &aTrack, ENDPOINT_T endPoint, TEARDROP_TYPE type); bool Create(TRACK &aTrack, ENDPOINT_T endPoint, TEARDROP_TYPE type); void GetCoordinates(std::vector<VECTOR2I> &points); void GetCoordinates(std::vector<VECTOR2I> &points) const {points = m_coordinates;} private: private: ///> Contains the type of teardrop ///> Contains the type of teardrop Loading @@ -63,7 +63,7 @@ private: ///> \a m_upperSegment and \a m_lowerSegment contain coordinates of segments composing a teardrop ///> \a m_upperSegment and \a m_lowerSegment contain coordinates of segments composing a teardrop std::vector<VECTOR2I> m_upperSegment; std::vector<VECTOR2I> m_upperSegment; std::vector<VECTOR2I> m_lowerSegment; std::vector<VECTOR2I> m_lowerSegment; std::vector<VECTOR2I> vect; std::vector<VECTOR2I> m_coordinates; /** /** * @brief Function \a CurvedSegments computes several points on deltoid curve and moves * @brief Function \a CurvedSegments computes several points on deltoid curve and moves Loading @@ -73,11 +73,9 @@ private: * See deltiod description and its parametric equations on [wiki page](http://en.wikipedia.org/wiki/Deltoid_curve). * See deltiod description and its parametric equations on [wiki page](http://en.wikipedia.org/wiki/Deltoid_curve). * @param [in] aTrack defines a vector along which the curved segments should be built * @param [in] aTrack defines a vector along which the curved segments should be built * @param [in] aVia used as the center of coordinates * @param [in] aVia used as the center of coordinates * @param [out] upperSegment vector contains the coordinates of computed segments * @param [out] lowerSegment vector contains the coordinates of mirrored segments * @return \a true in case the segments were successfully built and \a false otherwise * @return \a true in case the segments were successfully built and \a false otherwise */ */ bool CurvedSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECTOR2I> &upperSegment, std::vector<VECTOR2I> &lowerSegment); bool CurvedSegments(TRACK &aTrack, const VIA &aVia); /** /** * @brief Function \a StraightSegments builds two tangent lines for a circle from a givent point. * @brief Function \a StraightSegments builds two tangent lines for a circle from a givent point. Loading @@ -86,11 +84,9 @@ private: * @param [in] aTrack defines a vector along which the segments should be built * @param [in] aTrack defines a vector along which the segments should be built * @param [in] aVia represents a circle to which the segments should be built * @param [in] aVia represents a circle to which the segments should be built * @param [in] distance is distance ratio (in percent) from circle center in respect to its diameter * @param [in] distance is distance ratio (in percent) from circle center in respect to its diameter * @param [out] upperSegment vector contains the coordinates of computed segments * @param [out] lowerSegment vector contains the coordinates of mirrored segments * @return \a true in case the segments were successfully built and \a false otherwise * @return \a true in case the segments were successfully built and \a false otherwise */ */ bool StraightSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECTOR2I> &upperSegment, std::vector<VECTOR2I> &lowerSegment, int distance); bool StraightSegments(TRACK &aTrack, const VIA &aVia, int distance); /** /** * @brief Function SetVector creates a vector from \a aTrack directed into \a aVia * @brief Function SetVector creates a vector from \a aTrack directed into \a aVia Loading @@ -103,6 +99,11 @@ private: BOARD_CONNECTED_ITEM* GetObjectOnEnd(TRACK &aTrack, ENDPOINT_T endPoint); BOARD_CONNECTED_ITEM* GetObjectOnEnd(TRACK &aTrack, ENDPOINT_T endPoint); void SplitSegment(const SEG &segment, int splits, std::vector<VECTOR2I> &points); void SplitSegment(const SEG &segment, int splits, std::vector<VECTOR2I> &points); inline void PointOnCurve(int angle, double radius, VECTOR2I &point) { double coeff = M_PI / 180.0; point.x = 2 * radius * cos(coeff * angle) + radius * cos(2 * coeff * angle); point.y = 2 * radius * sin(coeff * angle) - radius * sin(2 * coeff * angle); } }; }; #endif // CLASS_TEARDROP_H #endif // CLASS_TEARDROP_H pcbnew/tools/edit_teardrops.cpp +3 −0 Original line number Original line Diff line number Diff line Loading @@ -204,6 +204,9 @@ bool TEARDROPS_EDITOR::DrawSegments(TEARDROP &teardrop, TRACK &aTrack) std::vector<TRACK *> tracks; std::vector<TRACK *> tracks; std::vector<VECTOR2I> coordinates; std::vector<VECTOR2I> coordinates; teardrop.GetCoordinates(coordinates); teardrop.GetCoordinates(coordinates); assert(coordinates.size() != 0); wxPoint currentPoint(0, 0); wxPoint currentPoint(0, 0); wxPoint prevPoint(coordinates[0].x, coordinates[0].y); wxPoint prevPoint(coordinates[0].x, coordinates[0].y); Loading Loading
pcbnew/class_teardrop.cpp +81 −48 Original line number Original line Diff line number Diff line Loading @@ -3,6 +3,7 @@ #include "class_board_item.h" #include "class_board_item.h" #include "class_undoredo_container.h" #include "class_undoredo_container.h" #include "geometry/seg.h" #include "geometry/seg.h" #include "geometry/shape_circle.h" #include "router/pns_utils.h" #include "router/pns_utils.h" TEARDROP::TEARDROP() TEARDROP::TEARDROP() Loading Loading @@ -36,22 +37,15 @@ bool TEARDROP::Create(TRACK &aTrack, ENDPOINT_T endPoint, TEARDROP_TYPE type = T } } if (type == TEARDROP_STRAIGHT) { if (type == TEARDROP_STRAIGHT) { result = StraightSegments(aTrack, *aVia, m_upperSegment, m_lowerSegment, 100); result = StraightSegments(aTrack, *aVia, 100); } } else if (type == TEARDROP_CURVED) { else if (type == TEARDROP_CURVED) { result = CurvedSegments(aTrack, *aVia, m_upperSegment, m_lowerSegment); result = CurvedSegments(aTrack, *aVia); } } return result; return result; } } void TEARDROP::GetCoordinates(std::vector<VECTOR2I> &points) { // points.insert(points.end(), m_upperSegment.begin(), m_upperSegment.end()); // points.insert(points.end(), m_lowerSegment.begin(), m_lowerSegment.end()); points = vect; } bool TEARDROP::SetVector(TRACK &aTrack, const VIA & aVia, VECTOR2I &startPoint, VECTOR2I &endPoint) bool TEARDROP::SetVector(TRACK &aTrack, const VIA & aVia, VECTOR2I &startPoint, VECTOR2I &endPoint) { { // Decide which end of the track is inside via and set this point as end of vector // Decide which end of the track is inside via and set this point as end of vector Loading @@ -72,10 +66,12 @@ bool TEARDROP::SetVector(TRACK &aTrack, const VIA & aVia, VECTOR2I &startPoint, return true; return true; } } bool TEARDROP::CurvedSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECTOR2I> &upperSegment, std::vector<VECTOR2I> &lowerSegment) bool TEARDROP::CurvedSegments(TRACK &aTrack, const VIA &aVia) { { VECTOR2I startPoint(0, 0); VECTOR2I startPoint(0, 0); VECTOR2I endPoint(0, 0); VECTOR2I endPoint(0, 0); std::vector<VECTOR2I> upperSegment; std::vector<VECTOR2I> lowerSegment; if ( !SetVector(aTrack, aVia, startPoint, endPoint) ) { if ( !SetVector(aTrack, aVia, startPoint, endPoint) ) { return false; return false; Loading @@ -90,29 +86,76 @@ bool TEARDROP::CurvedSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECTOR VECTOR2I point(0, 0); VECTOR2I point(0, 0); VECTOR2I viaCenter(aVia.GetPosition().x, aVia.GetPosition().y); VECTOR2I viaCenter(aVia.GetPosition().x, aVia.GetPosition().y); double coeff = M_PI / 180.0; VECTOR2I apertureUpper(0, 0); VECTOR2I apertureLower(0, 0); double radius = (aVia.GetWidth() / 2) - (aTrack.GetWidth() / 2); double radius = (aVia.GetWidth() / 2) - (aTrack.GetWidth() / 2); double rotationAngle = VECTOR2I(startPoint - endPoint).Angle(); double rotationAngle = VECTOR2I(startPoint - endPoint).Angle(); // Calculate segments of deltoid // Calculate the segments of deltoid composing the outline of a teardrop for ( int i = 10; i <= 60; i = i + 10 ) { for ( int i = 10; i <= 60; i = i + 10 ) { point.x = 2 * radius * cos(coeff * i) + radius * cos(2 * coeff * i); PointOnCurve(i, radius, point); point.y = 2 * radius * sin(coeff * i) - radius * sin(2 * coeff * i); point = point.Rotate(rotationAngle); point = point.Rotate(rotationAngle); point += viaCenter; point += viaCenter; upperSegment.push_back(point); m_coordinates.push_back(point); if (i == 50) { apertureUpper = point; } } } for ( int i = 300; i <= 350; i = i + 10 ) { for ( int i = 300; i <= 350; i = i + 10 ) { point.x = 2 * radius * cos(coeff * i) + radius * cos(2 * coeff * i); PointOnCurve(i, radius, point); point.y = 2 * radius * sin(coeff * i) - radius * sin(2 * coeff * i); point = point.Rotate(rotationAngle); point += viaCenter; m_coordinates.push_back(point); if (i == 340) { apertureLower = point; } } // Calculate the number of segments needed to fill the area inside the teardrop if (aVia.GetWidth() / 2 > 2 * aTrack.GetWidth()) { // First, calculate the distance between two points on both sides of the track and // number of iterations required to fill the zone SEG aperture(apertureUpper, apertureLower); int numSegments = aperture.Length() / aTrack.GetWidth(); int delta = radius / numSegments; for (int iteration = 0; iteration < numSegments; iteration++) { radius = radius - delta; for ( int i = 10; i <= 60; i = i + 10 ) { PointOnCurve(i, radius, point); point = point.Rotate(rotationAngle); point += viaCenter; if (i == 10) { int distance = SEG(viaCenter, point).Length(); if (distance < aVia.GetWidth() / 2) { break; } } m_coordinates.push_back(point); } lowerSegment.clear(); for ( int i = 350; i >= 300; i = i - 10 ) { PointOnCurve(i, radius, point); point = point.Rotate(rotationAngle); point = point.Rotate(rotationAngle); point += viaCenter; point += viaCenter; if (i == 350) { int distance = SEG(viaCenter, point).Length(); if (distance < aVia.GetWidth() / 2) { break; } } lowerSegment.push_back(point); lowerSegment.push_back(point); } } // Revert coordinates order for (std::vector<VECTOR2I>::reverse_iterator iter = lowerSegment.rbegin(); iter != lowerSegment.rend(); ++iter) { m_coordinates.push_back(*iter); } } } return true; return true; } } bool TEARDROP::StraightSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECTOR2I> &upperSegment, std::vector<VECTOR2I> &lowerSegment, int distance = 100) bool TEARDROP::StraightSegments(TRACK &aTrack, const VIA &aVia, int distance = 100) { { VECTOR2I startPoint(0, 0); VECTOR2I startPoint(0, 0); VECTOR2I endPoint(0, 0); VECTOR2I endPoint(0, 0); Loading Loading @@ -154,12 +197,8 @@ bool TEARDROP::StraightSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECT upperPoint += viaCenter; upperPoint += viaCenter; lowerPoint += viaCenter; lowerPoint += viaCenter; upperSegment.push_back(linePoint); upperSegment.push_back(upperPoint); // Calculate the number of segments needed to fill the area inside the teardrop // Calculate the number of segments needed to fill the area inside the teardrop std::vector<VECTOR2I> splitPoints; std::vector<VECTOR2I> splitPoints; int vertexNum = 1; if (aVia.GetWidth() / 2 > 2 * aTrack.GetWidth()) { if (aVia.GetWidth() / 2 > 2 * aTrack.GetWidth()) { // First, calculate the intersection point of the circle and one hand of the teardrop // First, calculate the intersection point of the circle and one hand of the teardrop r = aVia.GetWidth() / 2; r = aVia.GetWidth() / 2; Loading @@ -170,60 +209,54 @@ bool TEARDROP::StraightSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECT x = (upperPoint.x - startPoint.x) * t + startPoint.x; x = (upperPoint.x - startPoint.x) * t + startPoint.x; y = (upperPoint.y - startPoint.y) * t + startPoint.y; y = (upperPoint.y - startPoint.y) * t + startPoint.y; VECTOR2I intersectionPoint((int)x, (int)y); VECTOR2I intersectionPoint((int)x, (int)y); DrawDebugPoint(intersectionPoint, 5); // Second, calculate the distance between the track given and the intersection point // Second, calculate the distance between the given track and the intersection point SEG trackSegment(aTrack.GetStart().x, aTrack.GetStart().y, aTrack.GetEnd().x, aTrack.GetEnd().y); SEG trackSegment(aTrack.GetStart().x, aTrack.GetStart().y, aTrack.GetEnd().x, aTrack.GetEnd().y); int dist = trackSegment.LineDistance(intersectionPoint); int dist = trackSegment.LineDistance(intersectionPoint); int numSegments = 2 * dist / aTrack.GetWidth(); int numSegments = 2 * dist / aTrack.GetWidth(); // Third, subdivide radius of the via and build additional segments // Third, subdivide the diameter of the via and build additional segments SEG segRadius = SEG(upperPoint, lowerPoint); SEG segDiameter = SEG(upperPoint, lowerPoint); // SEG segRadius = SEG(upperPoint, viaCenter); SplitSegment(segDiameter, numSegments, splitPoints); SplitSegment(segRadius, numSegments, splitPoints); } } std::list<VECTOR2I> pts; std::list<VECTOR2I> outlinePoints; pts.push_back(upperPoint); outlinePoints.push_back(upperPoint); for (size_t i = 0; i < splitPoints.size(); i++) { for (size_t i = 0; i < splitPoints.size(); i++) { pts.push_back(splitPoints[i]); outlinePoints.push_back(splitPoints[i]); } } pts.push_back(lowerPoint); outlinePoints.push_back(lowerPoint); vertexNum = 0; // Biuld triangles filling the teardrop std::list<VECTOR2I>::iterator iter = pts.begin(); int vertexNum = 0; while ( iter != pts.end() ) { std::list<VECTOR2I>::iterator iter = outlinePoints.begin(); while ( iter != outlinePoints.end() ) { switch (vertexNum) { switch (vertexNum) { case 0: case 0: vect.push_back(linePoint); m_coordinates.push_back(linePoint); vertexNum++; vertexNum++; break; break; case 1: case 1: vect.push_back(*iter); m_coordinates.push_back(*iter); vertexNum++; vertexNum++; iter++; iter++; break; break; case 2: case 2: vect.push_back(*iter); m_coordinates.push_back(*iter); vertexNum = 0; vertexNum = 0; iter++; iter++; break; break; default:break; default:break; } } } } // Append additional vertexies in order to finish last triangle if (vertexNum == 0) { if (vertexNum == 0) { vect.push_back(linePoint); m_coordinates.push_back(linePoint); } } else if (vertexNum == 2) { else if (vertexNum == 2) { vect.push_back(vect[vect.size() - 3]); m_coordinates.push_back(m_coordinates[m_coordinates.size() - 3]); vect.push_back(linePoint); m_coordinates.push_back(linePoint); } for (size_t i = 0; i < vect.size(); i++) { printf("%d, %d\n", vect[i].x, vect[i].y); } } // lowerSegment.push_back(lowerPoint); // lowerSegment.push_back(linePoint); return true; return true; } } Loading
pcbnew/class_teardrop.h +9 −8 Original line number Original line Diff line number Diff line Loading @@ -55,7 +55,7 @@ public: */ */ bool Create(TRACK &aTrack, ENDPOINT_T endPoint, TEARDROP_TYPE type); bool Create(TRACK &aTrack, ENDPOINT_T endPoint, TEARDROP_TYPE type); void GetCoordinates(std::vector<VECTOR2I> &points); void GetCoordinates(std::vector<VECTOR2I> &points) const {points = m_coordinates;} private: private: ///> Contains the type of teardrop ///> Contains the type of teardrop Loading @@ -63,7 +63,7 @@ private: ///> \a m_upperSegment and \a m_lowerSegment contain coordinates of segments composing a teardrop ///> \a m_upperSegment and \a m_lowerSegment contain coordinates of segments composing a teardrop std::vector<VECTOR2I> m_upperSegment; std::vector<VECTOR2I> m_upperSegment; std::vector<VECTOR2I> m_lowerSegment; std::vector<VECTOR2I> m_lowerSegment; std::vector<VECTOR2I> vect; std::vector<VECTOR2I> m_coordinates; /** /** * @brief Function \a CurvedSegments computes several points on deltoid curve and moves * @brief Function \a CurvedSegments computes several points on deltoid curve and moves Loading @@ -73,11 +73,9 @@ private: * See deltiod description and its parametric equations on [wiki page](http://en.wikipedia.org/wiki/Deltoid_curve). * See deltiod description and its parametric equations on [wiki page](http://en.wikipedia.org/wiki/Deltoid_curve). * @param [in] aTrack defines a vector along which the curved segments should be built * @param [in] aTrack defines a vector along which the curved segments should be built * @param [in] aVia used as the center of coordinates * @param [in] aVia used as the center of coordinates * @param [out] upperSegment vector contains the coordinates of computed segments * @param [out] lowerSegment vector contains the coordinates of mirrored segments * @return \a true in case the segments were successfully built and \a false otherwise * @return \a true in case the segments were successfully built and \a false otherwise */ */ bool CurvedSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECTOR2I> &upperSegment, std::vector<VECTOR2I> &lowerSegment); bool CurvedSegments(TRACK &aTrack, const VIA &aVia); /** /** * @brief Function \a StraightSegments builds two tangent lines for a circle from a givent point. * @brief Function \a StraightSegments builds two tangent lines for a circle from a givent point. Loading @@ -86,11 +84,9 @@ private: * @param [in] aTrack defines a vector along which the segments should be built * @param [in] aTrack defines a vector along which the segments should be built * @param [in] aVia represents a circle to which the segments should be built * @param [in] aVia represents a circle to which the segments should be built * @param [in] distance is distance ratio (in percent) from circle center in respect to its diameter * @param [in] distance is distance ratio (in percent) from circle center in respect to its diameter * @param [out] upperSegment vector contains the coordinates of computed segments * @param [out] lowerSegment vector contains the coordinates of mirrored segments * @return \a true in case the segments were successfully built and \a false otherwise * @return \a true in case the segments were successfully built and \a false otherwise */ */ bool StraightSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECTOR2I> &upperSegment, std::vector<VECTOR2I> &lowerSegment, int distance); bool StraightSegments(TRACK &aTrack, const VIA &aVia, int distance); /** /** * @brief Function SetVector creates a vector from \a aTrack directed into \a aVia * @brief Function SetVector creates a vector from \a aTrack directed into \a aVia Loading @@ -103,6 +99,11 @@ private: BOARD_CONNECTED_ITEM* GetObjectOnEnd(TRACK &aTrack, ENDPOINT_T endPoint); BOARD_CONNECTED_ITEM* GetObjectOnEnd(TRACK &aTrack, ENDPOINT_T endPoint); void SplitSegment(const SEG &segment, int splits, std::vector<VECTOR2I> &points); void SplitSegment(const SEG &segment, int splits, std::vector<VECTOR2I> &points); inline void PointOnCurve(int angle, double radius, VECTOR2I &point) { double coeff = M_PI / 180.0; point.x = 2 * radius * cos(coeff * angle) + radius * cos(2 * coeff * angle); point.y = 2 * radius * sin(coeff * angle) - radius * sin(2 * coeff * angle); } }; }; #endif // CLASS_TEARDROP_H #endif // CLASS_TEARDROP_H
pcbnew/tools/edit_teardrops.cpp +3 −0 Original line number Original line Diff line number Diff line Loading @@ -204,6 +204,9 @@ bool TEARDROPS_EDITOR::DrawSegments(TEARDROP &teardrop, TRACK &aTrack) std::vector<TRACK *> tracks; std::vector<TRACK *> tracks; std::vector<VECTOR2I> coordinates; std::vector<VECTOR2I> coordinates; teardrop.GetCoordinates(coordinates); teardrop.GetCoordinates(coordinates); assert(coordinates.size() != 0); wxPoint currentPoint(0, 0); wxPoint currentPoint(0, 0); wxPoint prevPoint(coordinates[0].x, coordinates[0].y); wxPoint prevPoint(coordinates[0].x, coordinates[0].y); Loading