예제 #1
0
TSeqPos CPacked_seqpnt::GetStop(ESeqLocExtremes ext) const
{
    if (!GetPoints().empty()) {
        return (ext == eExtreme_Positional  &&  x_IsMinusStrand()) ?
            GetPoints().front() : GetPoints().back();
    }
    return kInvalidSeqPos;
}
예제 #2
0
// Returns true if there is no collision, and false if there is a collision.
bool TestSAT(AABB a, AABB b)
{
	// Since these are AABB collisions, we can easily determine the normals. That said, this was left this way for understanding and future implementation.
	// The first step is to get the normals for the two colliding objects, as these will be the axes on which we test for collisions.
	std::vector<glm::vec3> aNormals = GetNormals(a);
	std::vector<glm::vec3> bNormals = GetNormals(b);
	
	// A quick method that exists for getting the points of the AABB. In a regular implementation, we might instead pass in the actual points to this algorithm, skipping
	// this step.
	std::vector<glm::vec3> aPoints = GetPoints(a);
	std::vector<glm::vec3> bPoints = GetPoints(b);

	// This boolean gets returned, and will be true if there is no collision.
	bool isSeparated = false;

	// For each normal
	for (int i = 0; i < aNormals.size(); i++)
	{
		// Get the Min and Max projections for each object along the normal.
		float aMin, aMax;
		GetMinMax(aPoints, aNormals[i], aMin, aMax);

		float bMin, bMax;
		GetMinMax(bPoints, aNormals[i], bMin, bMax);

		// If the maximum projection of one of the objects is less than the minimum projection of the other object, then we can determine that there is a separation 
		// along this axis. Thus, we set isSeparated to true and break out of the for loop.
		isSeparated = aMax < bMin || bMax < aMin;
		if (isSeparated) break;
	}

	// This only runs if we still haven't proven that there is a separation between the two objects.
	// SAT is an optimistic algorithm in that it will stop the moment it determines there isn't a collision, and as such the less collisions there are the faster it will run.
	if (!isSeparated)
	{
		// Loop through the normals for the second object.
		// Note that since this is an AABB, the normals will be the same as the previous object. Again, this is left for future implementation and understanding.
		// The process below is exactly the same as above, only with object b's normals instead of object a.
		for (int i = 0; i < bNormals.size(); i++)
		{
			float aMin, aMax;
			GetMinMax(aPoints, bNormals[i], aMin, aMax);

			float bMin, bMax;
			GetMinMax(bPoints, bNormals[i], bMin, bMax);

			isSeparated = aMax < bMin || bMax < aMin;
			if (isSeparated) break;
		}
	}

	// At this point, isSeparated has been tested against each normal. If it has been set to true, then there is a separation. If it is false, that means none of the axes 
	// were separated, and there is a collision.
	return isSeparated;
}
예제 #3
0
bool DragRect::PtIn(const DPoint& pt) const {
    // Look at the z portion of the cross product on each side. The result
    // should be all negative or positive to be inside.

    DPoint apt[4];
    GetPoints(apt);

    double d0 = (pt.x - apt[0].x) * (apt[1].y - apt[0].y) -
            (pt.y - apt[0].y) * (apt[1].x - apt[0].x);
    double d1 = (pt.x - apt[1].x) * (apt[2].y - apt[1].y) -
            (pt.y - apt[1].y) * (apt[2].x - apt[1].x);
    double d2 = (pt.x - apt[2].x) * (apt[3].y - apt[2].y) -
            (pt.y - apt[2].y) * (apt[3].x - apt[2].x);
    double d3 = (pt.x - apt[3].x) * (apt[0].y - apt[3].y) -
            (pt.y - apt[3].y) * (apt[0].x - apt[3].x);

    if (d0 < 0.0 && d1 < 0.0 && d2 < 0.0 && d3 < 0.0) {
        return true;
    }
    if (d0 >= 0.0 && d1 >= 0.0 && d2 >= 0.0 && d3 >= 0.0) {
        return true;
    }

    return false;
}
예제 #4
0
void ArenaTeam::UpdateArenaPointsHelper(std::map<uint32, uint32>& playerPoints)
{
    // Called after a match has ended and the stats are already modified
    // Helper function for arena point distribution (this way, when distributing, no actual calculation is required, just a few comparisons)
    // 10 played games per week is a minimum
    if (Stats.WeekGames < 10)
        return;

    // To get points, a player has to participate in at least 30% of the matches
    uint32 requiredGames = (uint32)ceil(Stats.WeekGames * 0.3f);

    for (MemberList::const_iterator itr = Members.begin(); itr !=  Members.end(); ++itr)
    {
        // The player participated in enough games, update his points
        uint32 pointsToAdd = 0;
        if (itr->WeekGames >= requiredGames)
            pointsToAdd = GetPoints(itr->PersonalRating);

        std::map<uint32, uint32>::iterator player_itr = playerPoints.find(GUID_LOPART(itr->Guid));
        if (player_itr != playerPoints.end())
        {
            // Check if there is already more points
            if (player_itr->second < pointsToAdd)
                playerPoints[GUID_LOPART(itr->Guid)] = pointsToAdd;
        }
        else
            playerPoints[GUID_LOPART(itr->Guid)] = pointsToAdd;
    }
}
예제 #5
0
파일: geometry.cpp 프로젝트: kangaroo/moon
void
PolyBezierSegment::Append (moon_path *path)
{
	PointCollection *col;
	GPtrArray *points;

	col = GetPoints ();
	int points_count = col->GetCount ();

	// we need at least 3 points
	if (!col || (points_count % 3) != 0)
		return;

	points = col->Array();
	
	for (int i = 0; i < points_count - 2; i += 3) {
		moon_curve_to (path,
			       ((Value*)g_ptr_array_index(points, i))->AsPoint()->x,
			       ((Value*)g_ptr_array_index(points, i))->AsPoint()->y,

			       ((Value*)g_ptr_array_index(points, i+1))->AsPoint()->x,
			       ((Value*)g_ptr_array_index(points, i+1))->AsPoint()->y,

			       ((Value*)g_ptr_array_index(points, i+2))->AsPoint()->x,
			       ((Value*)g_ptr_array_index(points, i+2))->AsPoint()->y);
	}
}
예제 #6
0
파일: Tan.cpp 프로젝트: reverant/Tangram
bool Tan::IsOutsidePanel(){
    wxPoint* points=GetPoints();
    for(int i=0;i<GetSize();i++){
        if(points[i].x < 0 || points[i].x > WIDTH || points[i].y < 0 || points[i].y > HEIGHT) return true;
    }   
    return false;
}
예제 #7
0
std::vector<sf::Vector2f> Polygon::GetAxes()
{
	std::vector<sf::Vector2f> result;

	auto points = GetPoints();
	double length;
	sf::Vector2f axis, edge;
	for (int i = 0; i < points.size(); ++i)
	{
		//Calculate the edge between each point and its neighbor
		edge.x = points[(i + 1) % points.size()].x - points[i].x;
		edge.y = points[(i + 1) % points.size()].y - points[i].y;

		//Get length of edge
		length = sqrt(edge.x * edge.x + edge.y * edge.y);

		//Normalize
		edge.x /= length;
		edge.y /= length;

		//Push the pependiular vector to edge into the axes vector
		result.push_back(sf::Vector2f(-edge.y, edge.x));
	}

	return result;
}
예제 #8
0
void Polygon::CalculateCentroid()
{
	auto points = GetPoints();
	int nextIndex;
	sf::Vector2f centroid;
	double area = 0;

	for (int i = 0; i < points.size(); ++i)
	{
		nextIndex = (i + 1) % points.size();
		area += (points[i].x*points[nextIndex].y - points[nextIndex].x*points[i].y);
	}
	area /= 2;

	for (int i = 0; i < points.size(); ++i)
	{
		nextIndex = (i + 1) % points.size();
		centroid.x += (points[i].x + points[nextIndex].x)*(points[i].x*points[nextIndex].y - points[nextIndex].x*points[i].y);
		centroid.y += (points[i].y + points[nextIndex].y)*(points[i].x*points[nextIndex].y - points[nextIndex].x*points[i].y);

	}

	centroid.x /= (6 * area);
	centroid.y /= (6 * area);

	m_originalCentroidPosition = centroid;

	m_shape.setOrigin(centroid);

}
예제 #9
0
void ArenaTeam::UpdateArenaPointsHelper(std::map<uint32, uint32>& PlayerPoints)
{
    // called after a match has ended and the stats are already modified
    // helper function for arena point distribution (this way, when distributing, no actual calculation is required, just a few comparisons)
    // 10 played games per week is a minimum
    if (m_stats.games_week < 10)
        return;
    // to get points, a player has to participate in at least 30% of the matches
    uint32 min_plays = (uint32) ceil(m_stats.games_week * 0.3);
    for (MemberList::const_iterator itr = m_members.begin(); itr !=  m_members.end(); ++itr)
    {
        // the player participated in enough games, update his points
        uint32 points_to_add = 0;
        if (itr->games_week >= min_plays)
            points_to_add = GetPoints(itr->personal_rating);
        // OBSOLETE : CharacterDatabase.PExecute("UPDATE arena_team_member SET points_to_add = '%u' WHERE arenateamid = '%u' AND guid = '%u'", points_to_add, m_TeamId, itr->guid);

        std::map<uint32, uint32>::iterator plr_itr = PlayerPoints.find(GUID_LOPART(itr->guid));
        if (plr_itr != PlayerPoints.end())
        {
            //check if there is already more points
            if (plr_itr->second < points_to_add)
                PlayerPoints[GUID_LOPART(itr->guid)] = points_to_add;
        }
        else
            PlayerPoints[GUID_LOPART(itr->guid)] = points_to_add;
    }
}
예제 #10
0
파일: geometry.cpp 프로젝트: kangaroo/moon
int
PolyLineSegment::GetPathSize ()
{
	PointCollection *points = GetPoints ();
	int n = points ? points->GetCount() : 0;
	
	return n * MOON_PATH_LINE_TO_LENGTH;
}
예제 #11
0
FilterPoints2::FilterPoints2(potrace_path_t *path, float proportionXY, /*float tolerance, */float minlen)
{
	Path = path;
	koefProportionXY = proportionXY;
	//Tolerance = tolerance;
	MinLen = minlen;
	GetPoints();
}
예제 #12
0
파일: geometry.cpp 프로젝트: kangaroo/moon
int
PolyBezierSegment::GetPathSize ()
{
	PointCollection *points = GetPoints ();
	int n = points ? points->GetCount() : 0;

	return (n / 3) * MOON_PATH_CURVE_TO_LENGTH;
}
예제 #13
0
BOOL CGauge::OnDragStart(int nHitTest,CPointF point)
{
	REAL dx = m_pWnd->GetStartPos().x;
	REAL dy = m_pWnd->GetStartPos().y;

	CRectF rc;
	GetBoundsRect(rc);
	rc.OffsetRect(-dx,-dy);

	BOOL bRet = FALSE;

	CClientDC dc(m_pWnd);
	CElastic elastic(&dc,this);

	CPoints pts;

	switch (nHitTest)
	{
	case TopLeft:
		PointHelper::RecalcPoints(m_rcBounds,CRectF(point.x,point.y,rc.right,rc.bottom),m_pts,pts);
		break;
	case Top:
		PointHelper::RecalcPoints(m_rcBounds,CRectF(rc.left,point.y,rc.right,rc.bottom),m_pts,pts);
		break;
	case TopRight:
		PointHelper::RecalcPoints(m_rcBounds,CRectF(rc.left,point.y,point.x,rc.bottom),m_pts,pts);
		break; 
	case Right:
		PointHelper::RecalcPoints(m_rcBounds,CRectF(rc.left,rc.top,point.x,rc.bottom),m_pts,pts);
		break;
	case BottomRight:
		PointHelper::RecalcPoints(m_rcBounds,CRectF(rc.left,rc.top,point.x,point.y),m_pts,pts);
		break;
	case Bottom:
		PointHelper::RecalcPoints(m_rcBounds,CRectF(rc.left,rc.top,rc.right,point.y),m_pts,pts);
		break;
	case BottomLeft:
		PointHelper::RecalcPoints(m_rcBounds,CRectF(point.x,rc.top,rc.right,point.y),m_pts,pts);
		break;
	case Left:
		PointHelper::RecalcPoints(m_rcBounds,CRectF(point.x,rc.top,rc.right,rc.bottom),m_pts,pts);
		break;
	case Body: 
		PointHelper::RecalcPoints(m_rcBounds,CRectF(rc.left,rc.top,rc.right,rc.bottom),m_pts,pts);
		bRet = TRUE;
		break;
	default:
		GetPoints(pts);
		PointHelper::OffsetPoints(pts,-dx,-dy);
		pts[nHitTest-HtIndex] = CPoint((int)point.x,(int)point.y);
		break;
	} 

	dc.Polyline(pts.GetData(),(int)pts.GetCount());

	return bRet;
}
예제 #14
0
/**
 * Send a new point request
 * @param point
 *
 * Info sent: AddPoints - Points...
 */
void Sender::sendPoints(Point* point)//std::vector<Point> points)
{
    std::string toSend = separator;
    toSend += NumberToString(ADD_POINTS);
    toSend += separator;

    toSend += GetPoints(point);

    client->sendMessage(toSend);
}
예제 #15
0
/**
 * @brief LengthBezier return spline length using 4 spline point.
 * @param p1 first spline point
 * @param p2 first control point.
 * @param p3 second control point.
 * @param p4 last spline point.
 * @return length.
 */
qreal VSpline::LengthBezier ( const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4 ) const
{
    QPainterPath splinePath;
    QVector<QPointF> points = GetPoints (p1, p2, p3, p4);
    splinePath.moveTo(points.at(0));
    for (qint32 i = 1; i < points.count(); ++i)
    {
        splinePath.lineTo(points.at(i));
    }
    return splinePath.length();
}
예제 #16
0
파일: bodyInst.cpp 프로젝트: X3llos/eng_new
void BodyInst::GetOBB(myBody *b)
{
  GetPoints(b);
  for(int i=0;i<8;i++)
  {
      float p[3] = {b->pts[i*3]-b->center[0],b->pts[i*3+1]-b->center[1], b->pts[i*3+2]-b->center[2]};
      QuaternionTransform(p, b->orientation);
      b->pts[i*3] = p[0]+b->center[0];
      b->pts[i*3+1] = p[1]+b->center[1];
      b->pts[i*3+2] = p[2]+b->center[2];
  }
}
예제 #17
0
파일: Tan.cpp 프로젝트: reverant/Tangram
wxPoint Tan::GetCenter(){
    wxPoint* points=GetPoints();
    int centerX=0;
    int centerY=0;
    for(int i=0;i<GetSize();i++){
        centerX+=points[i].x;
        centerY+=points[i].y;   
    }
    centerX/=GetSize();
    centerY/=GetSize();
    return wxPoint(centerX,centerY);
}
예제 #18
0
void Render::DrawGroup(Group group)
{
	Point points[3];
	for (int it = 0, index = group.first; it < group.count; ++it, ++index)
	{
	 GetPoints(index, points);
	 for (auto &item : points)
	 {
	  glVertex3dv(vertexes.at(item.vertex).v);
	 }
	}
}
예제 #19
0
파일: Tan.cpp 프로젝트: reverant/Tangram
bool Tan::IsCrossing(Tan* tan) {
    wxPoint* points=GetPoints();
    wxPoint* pointsToCheck=tan->GetPoints();
    for(int i=0;i<GetSize();i++){
        for(int j=0;j<tan->GetSize();j++){
            if(VectorUtils::IsCrossing(points[i],points[(i+1)%GetSize()],pointsToCheck[j],pointsToCheck[(j+1)%tan->GetSize()])) {
                return true;
            }
        }   
    }
    return false;
}
예제 #20
0
BOOL CDoc::FileOpen(LPCTSTR szFilename)
{
	GetPoints().clear();
	BOOL bResult = FALSE;

	try
	{
		CArchive ar(szFilename, CArchive::load);
		ar >> *this;
		bResult = TRUE;
	}

	catch (const CFileException &e)
	{
		// An exception occurred. Display the relevant information.
		::MessageBox(NULL, e.GetText(), _T("Failed to Load File"), MB_ICONWARNING);
		
		GetPoints().clear();
	}

	return bResult;
}
예제 #21
0
int AssignPointAttributeToCoordinatesFilter::RequestData(
    vtkInformation * /*request*/,
    vtkInformationVector ** inputVector,
    vtkInformationVector * outputVector)
{
    auto inData = vtkPointSet::SafeDownCast(inputVector[0]->GetInformationObject(0)->Get(vtkDataObject::DATA_OBJECT()));
    auto outData = vtkPointSet::SafeDownCast(outputVector->GetInformationObject(0)->Get(vtkDataObject::DATA_OBJECT()));

    auto previousPointCoords = inData->GetPoints()->GetData();
    vtkDataArray * pointsToAssign = nullptr;

    if (!this->AttributeArrayToAssign.empty())
    {
        auto newPoints = inData->GetPointData()->GetArray(this->AttributeArrayToAssign.c_str());
        if (!newPoints)
        {
            vtkErrorMacro("Array to assign not found in input data: " + this->AttributeArrayToAssign);
            return 0;
        }

        if (newPoints->GetNumberOfComponents() != 3
            || newPoints->GetNumberOfTuples() != inData->GetNumberOfPoints())
        {
            vtkErrorMacro("Component/Tuple count mismatching in selected data array: " + this->AttributeArrayToAssign);
            return 0;
        }
        pointsToAssign = newPoints;
    }

    outData->ShallowCopy(inData);

    if (pointsToAssign)
    {
        vtkNew<vtkPoints> newPoints;
        newPoints->SetData(pointsToAssign);
        outData->SetPoints(newPoints.Get());
    }

    // pass current point coordinates as point attribute
    if (previousPointCoords)
    {
        outData->GetPointData()->AddArray(previousPointCoords);
    }

    if (auto currentCoords = pointsToAssign ? pointsToAssign : previousPointCoords)
    {
        outData->GetPointData()->SetActiveScalars(currentCoords->GetName());
    }

    return 1;
}
예제 #22
0
void CGauge::Draw(CDC *pDC)
{
	CPoints pts;
	GetPoints(pts);

	pDC->Polyline(pts.GetData(),(int)pts.GetCount());

	CRect rc;
	pDC->DrawText(m_strDesc,rc,DT_CALCRECT);
	CPointF ptf(m_rcBounds.CenterPoint());
	CPoint pt((int)ptf.x,(int)ptf.y);
	rc.OffsetRect(pt-rc.CenterPoint());
	pDC->DrawText(m_strDesc,rc,DT_TOP);
}
예제 #23
0
void CDoc::Serialize(CArchive &ar)
// Uses CArchive to stream data to or from a file
{

	if (ar.IsStoring())
	{
		// Store the number of points
		UINT nPoints = GetPoints().size();
		ar << nPoints;
		
		// Store the PlotPoint data
		std::vector<PlotPoint>::iterator iter;
		for (iter = GetPoints().begin(); iter < GetPoints().end(); ++iter)
		{
			ArchiveObject ao( &(*iter), sizeof(PlotPoint) );
			ar << ao;
		}
	}
	else
	{
		UINT nPoints;
		PlotPoint pp = {0};
		GetPoints().clear();

		// Load the number of points
		ar >> nPoints;

		// Load the PlotPoint data
		for (UINT u = 0; u < nPoints; ++u)
		{
			ArchiveObject ao( &pp, sizeof(pp) );
			ar >> ao;
			GetPoints().push_back(pp);
		}
	}

}
예제 #24
0
파일: box.cpp 프로젝트: X3llos/eng_new
float* Box::GetOBB()
{
  GetPoints();
  float* center = GetCenter();
  for(int i=0;i<8;i++)
  {
      float p[3] = {pts[i*3]-center[0],pts[i*3+1]-center[1], pts[i*3+2]-center[2]};
      QuaternionTransform(p, GetOrientation());
      pts[i*3] = p[0]+center[0];
      pts[i*3+1] = p[1]+center[1];
      pts[i*3+2] = p[2]+center[2];
  }

  return pts;
}
예제 #25
0
int CGraphBSpline::Draw( CFmlDrawEngine& fde, const PointFde& tl, CNode* )
{
	RectFde rc = GetPositionRect();
	rc.translate( tl.x(), tl.y() );

	QVector<qint8> tp;
	QVector<PointFde> xy;
	GetPoints( rc, xy, tp );

	QColor color = (GetColor() == DEFAULT_GRAPH_COLOR ? ::getCurrentFormulatorStyle().getLogPen().m_color : GetColor());

	fde.DrawFillPath( xy, tp, FS_LogPen( color, (Qt::PenStyle) GetStyle(), GetWidth() ), FS_LogBrush(GetColor(), Qt::SolidPattern) );

	return 1;
}
예제 #26
0
// cppcheck-suppress unusedFunction
QVector<QPointF> VSpline::SplinePoints(const QPointF &p1, const QPointF &p4, qreal angle1, qreal angle2, qreal kAsm1,
                                       qreal kAsm2, qreal kCurve)
{
    QLineF p1pX(p1.x(), p1.y(), p1.x() + 100, p1.y());
    p1pX.setAngle( angle1 );
    qreal L = 0, radius = 0, angle = 90;
    radius = QLineF(QPointF(p1.x(), p4.y()), p4).length();
    L = kCurve * radius * 4 / 3 * tan( angle * M_PI / 180.0 / 4 );
    QLineF p1p2(p1.x(), p1.y(), p1.x() + L * kAsm1, p1.y());
    p1p2.setAngle(angle1);
    QLineF p4p3(p4.x(), p4.y(), p4.x() + L * kAsm2, p4.y());
    p4p3.setAngle(angle2);
    QPointF p2 = p1p2.p2();
    QPointF p3 = p4p3.p2();
    return GetPoints(p1, p2, p3, p4);
}
예제 #27
0
	void MeshPhysicsShape::Save(Archive& archive)
	{
		PhysicsSystem::SERIAL_CreateMesh.Save(archive);

		int count = GetNumPoints();
		archive.Write(&count);

		Vector3* verts = GetPoints();
		for (int x = 0; x < count; ++x)
		{
			archive.Write(&verts[x].x);
			archive.Write(&verts[x].y);
			archive.Write(&verts[x].z);
		}

		Vector3& scale = GetScale();
		archive.Write(&scale);
	}
예제 #28
0
파일: geometry.cpp 프로젝트: kangaroo/moon
void
PolyQuadraticBezierSegment::Append (moon_path *path)
{
	PointCollection *col;
	GPtrArray *points;
	int count;

	col = GetPoints ();
	if (!col)
		return;

	count = col->GetCount ();
	if ((count % 2) != 0)
		return;
	
	// origin
	double x0 = 0.0;
	double y0 = 0.0;
	moon_get_current_point (path, &x0, &y0);
	
	points = col->Array();

	// we need at least 2 points
	for (int i = 0; i < count - 1; i+=2) {
		double x1 = ((Value*)g_ptr_array_index(points, i))->AsPoint()->x;
		double y1 = ((Value*)g_ptr_array_index(points, i))->AsPoint()->y;
		double x2 = ((Value*)g_ptr_array_index(points, i+1))->AsPoint()->x;
		double y2 = ((Value*)g_ptr_array_index(points, i+1))->AsPoint()->y;
		double x3 = x2;
		double y3 = y2;
		
		x2 = x1 + (x2 - x1) / 3;
		y2 = y1 + (y2 - y1) / 3;
		x1 = x0 + 2 * (x1 - x0) / 3;
		y1 = y0 + 2 * (y1 - y0) / 3;
		
		moon_curve_to (path, x1, y1, x2, y2, x3, y3);
		
		// set new origin
		x0 = x3;
		y0 = y3;
	}
}
예제 #29
0
파일: geometry.cpp 프로젝트: kangaroo/moon
void
PolyLineSegment::Append (moon_path *path)
{
	PointCollection *col;
	GPtrArray *points;
	int count;

	col = GetPoints ();
	
	if (!col)
		return;

	points = col->Array();
	count = col->GetCount ();

	for (int i = 0; i < count; i++)
		moon_line_to (path,
			      ((Value*)g_ptr_array_index(points, i))->AsPoint()->x,
			      ((Value*)g_ptr_array_index(points, i))->AsPoint()->y);
}
예제 #30
0
void DragRect::ScrollExpand(dword maskA, dword maskB, double dx, double dy) {
    // This only applies when one finger is down. Imagine the map being
    // scrolled by dx, dy, and the scroll rect expanding. Basically, the
    // fixed point of the rect scrolls in the dx, dy direction.

    if (maskA != 0 && maskB != 0) {
        return;
    }

    // Simply "scroll" the fixed point

    DPoint pt;
    DPoint apt[4];
    GetPoints(apt);
    switch (maskA | maskB) {
    case 1:
        pt = apt[2];
        pt.x += dx;
        pt.y += dy;
        TrackPoint2(pt);
        break;
    case 2:
        pt = apt[3];
        pt.x += dx;
        pt.y += dy;
        TrackPoint3(pt);
        break;
    case 4:
        pt = apt[0];
        pt.x += dx;
        pt.y += dy;
        TrackPoint0(pt);
        break;
    case 8:
        pt = apt[1];
        pt.x += dx;
        pt.y += dy;
        TrackPoint1(pt);
        break;
    }
}