Commit 02b1319c authored by Mikhail Karpenko's avatar Mikhail Karpenko

Add TEARDROP class

parent b1cd83c1
#include "class_teardrop.h"
TEARDROP::TEARDROP(BOARD_ITEM *aParent) :
TRACK(aParent, PCB_TRACE_T)
{
m_type = TEARDROP_NONE;
}
bool TEARDROP::Create(TRACK &aTrack)
{
}
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
STATUS_FLAGS status = aTrack.IsPointOnEnds(wxPoint(aVia.GetPosition().x, aVia.GetPosition().y), aVia.GetWidth() / 2);
if (status == STARTPOINT) {
startPoint = aTrack.GetEnd();
endPoint = aTrack.GetStart();
}
else if (status == ENDPOINT) {
startPoint = aTrack.GetStart();
endPoint = aTrack.GetEnd();
}
else {
// The via is too far from any ends or the track is too short
return false;
}
return true;
}
bool TEARDROP::CurvedSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECTOR2I> &upperSegment, std::vector<VECTOR2I> &lowerSegment)
{
VECTOR2I startPoint(0, 0);
VECTOR2I endPoint(0, 0);
if ( !SetVector(aTrack, aVia, startPoint, endPoint) ) {
return false;
}
VECTOR2I point(0, 0);
VECTOR2I viaCenter(aVia.GetPosition().x, aVia.GetPosition().y);
double coeff = M_PI / 180.0;
double radius = (aVia.GetWidth() / 2) - (aTrack.GetWidth() / 2);
double rotationAngle = VECTOR2I(startPoint - endPoint).Angle();
// Calculate segments of deltoid
for ( int i = 10; i <= 60; i = i + 10 ) {
point.x = 2 * radius * cos(coeff * i) + radius * cos(2 * coeff * i);
point.y = 2 * radius * sin(coeff * i) - radius * sin(2 * coeff * i);
point = point.Rotate(rotationAngle);
point += viaCenter;
upperSegment.push_back(point);
}
for ( int i = 300; i <= 350; i = i + 10 ) {
point.x = 2 * radius * cos(coeff * i) + radius * cos(2 * coeff * i);
point.y = 2 * radius * sin(coeff * i) - radius * sin(2 * coeff * i);
point = point.Rotate(rotationAngle);
point += viaCenter;
lowerSegment.push_back(point);
}
return true;
}
bool TEARDROP::StraightSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECTOR2I> &upperSegment, std::vector<VECTOR2I> &lowerSegment, int distance = 100)
{
VECTOR2I startPoint(0, 0);
VECTOR2I endPoint(0, 0);
VECTOR2I viaCenter(aVia.GetPosition().x, aVia.GetPosition().y);
if ( !SetVector(aTrack, aVia, startPoint, endPoint) ) {
return false;
}
// Equation coefficients
double r = (aVia.GetWidth() / 2) + ((distance * aVia.GetWidth()) / (2 *100));
double a = pow((endPoint.x - startPoint.x), 2) + pow((endPoint.y - startPoint.y), 2);
double b = 2 * (double)(endPoint.x - startPoint.x) * (double)(startPoint.x - viaCenter.x) + 2 * (double)(endPoint.y - startPoint.y) * (double)(startPoint.y - viaCenter.y);
double c = pow((startPoint.x - viaCenter.x), 2) + pow((startPoint.y - viaCenter.y), 2) - pow(r, 2);
double t = 2 * c / (-b + sqrt(b * b - 4 * a * c));
double x = (endPoint.x - startPoint.x) * t + startPoint.x;
double y = (endPoint.y - startPoint.y) * t + startPoint.y;
VECTOR2I linePoint(x, y);
int correctedRadius = (aVia.GetWidth() / 2) - (aTrack.GetWidth() / 2);
c = pow((startPoint.x - viaCenter.x), 2) + pow((startPoint.y - viaCenter.y), 2) - pow(correctedRadius, 2);
t = 2 * c / (-b + sqrt(b * b - 4 * a * c));
x = (endPoint.x - startPoint.x) * t + startPoint.x;
y = (endPoint.y - startPoint.y) * t + startPoint.y;
VECTOR2I circlePoint(x, y);
VECTOR2I upperPoint = circlePoint - viaCenter;
VECTOR2I lowerPoint = upperPoint;
upperPoint = upperPoint.Rotate(M_PI / 2);
lowerPoint = lowerPoint.Rotate(-M_PI / 2);
upperPoint += viaCenter;
lowerPoint += viaCenter;
upperSegment.push_back(linePoint);
upperSegment.push_back(upperPoint);
lowerSegment.push_back(linePoint);
lowerSegment.push_back(lowerPoint);
return true;
}
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Elphel, Inc.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file class_teardrop.h
* @brief Definitions for teardrops.
*/
#ifndef CLASS_TEARDROP_H
#define CLASS_TEARDROP_H
#include "class_track.h"
class TEARDROP : public TRACK
{
public:
TEARDROP(BOARD_ITEM *aParent);
/**
* @brief Defines the type of a teardrop.
*/
typedef enum {
TEARDROP_NONE, /// The type is undefined
TEARDROP_STRAIGHT, /// The teardrop is created by two straight segments
TEARDROP_CURVED /// The teardrop is created by several segments approximating deltoid
} TEARDROP_TYPE;
/**
* @brief GetType returns the type of the teardrop.
* @return TEARDROP_TYPE
*/
TEARDROP_TYPE GetType() const {return m_type;}
/**
* @brief Function Create creates a teardrop(s) for a given track
* @param aTrack
* @return \a true in case the teardrops were successfully built and \a false otherwise
*/
bool Create(TRACK &aTrack);
private:
///> Contains the type of teardrop
TEARDROP_TYPE m_type;
///> \a m_upperSegment and \a m_lowerSegment contain actual segments composing a teardrop
std::vector<TRACK> m_upperSegment;
std::vector<TRACK> m_lowerSegment;
/**
* @brief Function \a CurvedSegments computes several points on deltoid curve and moves
* these points along the vector defined by \a aTrack.
*
* This function computes the coordinates of points only and does not build actual track segments.
* 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] 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
*/
bool CurvedSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECTOR2I> &upperSegment, std::vector<VECTOR2I> &lowerSegment);
/**
* @brief Function \a StraightSegments builds two tangent lines for a circle from a givent point.
*
* This function computes the coordinates of points only and does not build actual track segments.
* @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] 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
*/
bool StraightSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECTOR2I> &upperSegment, std::vector<VECTOR2I> &lowerSegment, int distance);
/**
* @brief Function SetVector creates a vector from \a aTrack directed into \a aVia
* @param aTrack is used to create a vector
* @param startPoint is start point of resulting vector
* @param endPoint is end point of resulting vector
* @return \a true in case the vector is created successfully and \a false otherwise
*/
bool SetVector(TRACK &aTrack, const VIA &aVia, VECTOR2I &startPoint, VECTOR2I &endPoint);
};
#endif // CLASS_TEARDROP_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment