示例#1
0
bool ApplyScale(m2::PointD const & pixelScaleCenter, double factor, ScreenBase & screen)
{
  m2::PointD const globalScaleCenter = screen.PtoG(screen.P3dtoP(pixelScaleCenter));

  ScreenBase tmp = screen;
  tmp.Scale(factor);
  tmp.MatchGandP3d(globalScaleCenter, pixelScaleCenter);

  if (!CheckMinScale(tmp))
    return false;

  m2::RectD const & worldR = df::GetWorldRect();

  if (!CheckBorders(tmp))
  {
    if (CanShrinkInto(tmp, worldR))
      tmp = ShrinkInto(tmp, worldR);
    else
      return false;
  }

  if (!CheckMaxScale(tmp))
    return false;

  // re-checking the borders, as we might violate them a bit (don't know why).
  if (!CheckBorders(tmp))
    tmp = ScaleInto(tmp, worldR);

  screen = tmp;
  return true;
}
示例#2
0
文件: navigator.cpp 项目: morsya/omim
void Navigator::DoDrag(m2::PointD const & pt, double /*timeInSec*/)
{
  if (m_LastPt1 == pt)
    return;

  ScreenBase const s = ShrinkInto(m_StartScreen, m_scales.GetWorldRect());

  double dx = pt.x - m_StartPt1.x;
  double dy = pt.y - m_StartPt1.y;

  ScreenBase tmp = s;
  tmp.Move(dx, 0);
  if (!CheckBorders(tmp))
    dx = 0;

  tmp = s;
  tmp.Move(0, dy);
  if (!CheckBorders(tmp))
    dy = 0;

  tmp = s;
  tmp.Move(dx, dy);

  if (CheckBorders(tmp))
  {
    m_StartScreen = tmp;
    m_StartPt1 = pt;
    m_LastPt1 = pt;
    m_Screen = tmp;
  }
}
示例#3
0
文件: navigator.cpp 项目: morsya/omim
void Navigator::SetOrg(m2::PointD const & org)
{
  ScreenBase tmp = m_Screen;
  tmp.SetOrg(org);
  if (CheckBorders(tmp))
    m_Screen = tmp;
}
示例#4
0
bool MapMaster::IsTransparent(int posx, int posy, int posz)
{
    if (!CheckBorders(&posx, &posy, &posz))
    {
        return false;
    }
    return squares_[posx][posy][posz]->IsTransparent();
}
示例#5
0
文件: navigator.cpp 项目: morsya/omim
bool Navigator::ScaleImpl(m2::PointD const & newPt1, m2::PointD const & newPt2,
                          m2::PointD const & oldPt1, m2::PointD const & oldPt2,
                          bool skipMinScaleAndBordersCheck,
                          bool doRotateScreen)
{
  math::Matrix<double, 3, 3> newM = m_Screen.GtoPMatrix() * ScreenBase::CalcTransform(oldPt1, oldPt2, newPt1, newPt2);

  double oldAngle = m_Screen.GetAngle();
  ScreenBase tmp = m_Screen;
  tmp.SetGtoPMatrix(newM);
  if (!doRotateScreen)
    tmp.Rotate(-(tmp.GetAngle() - oldAngle));

  if (!skipMinScaleAndBordersCheck && !CheckMinScale(tmp))
    return false;

  m2::RectD const & worldR = m_scales.GetWorldRect();

  if (!skipMinScaleAndBordersCheck && !CheckBorders(tmp))
  {
    if (CanShrinkInto(tmp, worldR))
      tmp = ShrinkInto(tmp, worldR);
    else
      return false;
  }

  if (!CheckMaxScale(tmp))
    return false;

  // re-checking the borders, as we might violate them a bit (don't know why).
  if (!CheckBorders(tmp))
    tmp = ScaleInto(tmp, worldR);

  m_Screen = tmp;
  return true;
}
示例#6
0
文件: dec.cpp 项目: AEonZR/GtkRadiant
void MakeDecimatedMap(int *NumNodes, int *NumTris, NODE **pNode, TRI **pTri)
{
	int  compare(TRITABLE *, TRITABLE *);
	int Bisect(NODE *, int, int, int);
	void CalcAngles(NODE *, int *, float *);
	void EdgeOnSide(int *, int *, int *);
	int tricall(int, NODE *, int *, TRI **, TRI **, const char *);
	int CheckBorders(int *,int,NODE *,int *,TRI **);

	float       biggesterror;
	int         i, j, N;
	int         j0, j1, j2;
	int         NumNodesToSave;
	int         NumNodesUsed;
	NODE        *Node;
	TRI         *Tri;
	TRITABLE    *TriTable;

	if(Decimate <= 0) return;
        /*
	ghCursorCurrent = LoadCursor(NULL,IDC_WAIT);
	SetCursor(ghCursorCurrent);
        */
	dh = (Hur-Hll)/NH;
	dv = (Vur-Vll)/NV;
	NVP1 = NV+1;

	NumNodes[0] = (NH+1)*(NVP1);
	*pNode = (NODE *) malloc(NumNodes[0] * sizeof(NODE));
	Node = *pNode;
	memset(Node,0,NumNodes[0]*sizeof(NODE));

	// Copy [NH][NV] vertex array to our working node array
	for(i=0,N=0; i<=NH; i++)
	{
		for(j=0; j<=NV; j++, N++)
		{
			Node[N].p[0]  = (float)xyz[i][j].p[0];
			Node[N].p[1]  = (float)xyz[i][j].p[1];
			Node[N].p[2]  = (float)xyz[i][j].p[2];
			Node[N].fixed = xyz[i][j].fixed;
		}
	}
	// Start things off with the corner values
	Node[ 0].used           = 1;
	Node[NV].used           = 1;
	Node[NH*NVP1].used    = 1;
	Node[NH*NVP1+NV].used = 1;
	NumNodesUsed = 4;
	tricall(NumNodes[0], Node, NumTris, NULL, pTri, "cnzBNPY");
	Tri = *pTri;

	// Which coordinates are we triangulating on?
	switch(Plane)
	{
	case PLANE_XZ0:
	case PLANE_XZ1:
		j0 = 1;
		j1 = 0;
		j2 = 2;
		break;
	case PLANE_YZ0:
	case PLANE_YZ1:
		j0 = 0;
		j1 = 1;
		j2 = 2;
		break;
	default:
		j0 = 2;
		j1 = 0;
		j2 = 1;
	}

	// TriTable stores the largest error in a triangle and the node where that
	// error occurs
	TriTable = (TRITABLE *) malloc(NH*NV*2 * sizeof(TRITABLE));
	NumNodesToSave = min(NumNodes[0], (int)(0.01*(100-Decimate)*(NumNodes[0]-NumNodesUsed)+NumNodesUsed));

	while(NumNodesUsed < NumNodesToSave)
	{
		for(i=0; i<NumTris[0]; i++)
			Tri[i].flag = 0;

		// For every node that's not currently used, find what triangle it
		// lies on, and the error at this node
		for(i=0, biggesterror=0; i<NumNodes[0]; i++)
		{
			if(Node[i].used) continue;
			for(j=0, Node[i].tri=-1; (j<NumTris[0]) && (Node[i].tri==-1); j++)
			{
				if( side(Node[i].p[j1],          Node[i].p[j2],
					     Node[Tri[j].v[0]].p[j1],Node[Tri[j].v[0]].p[j2],
					     Node[Tri[j].v[1]].p[j1],Node[Tri[j].v[1]].p[j2]) < 0. ) continue;
				if( side(Node[i].p[j1],          Node[i].p[j2],
					     Node[Tri[j].v[1]].p[j1],Node[Tri[j].v[1]].p[j2],
					     Node[Tri[j].v[2]].p[j1],Node[Tri[j].v[2]].p[j2]) < 0. ) continue;
				if( side(Node[i].p[j1],          Node[i].p[j2],
					     Node[Tri[j].v[2]].p[j1],Node[Tri[j].v[2]].p[j2],
					     Node[Tri[j].v[0]].p[j1],Node[Tri[j].v[0]].p[j2]) < 0. ) continue;
				Node[i].tri = j;
			}
			if(Node[i].tri < 0)
			{
                          /*
				ghCursorCurrent = ghCursorDefault;
				SetCursor(ghCursorCurrent);
                          */
				g_FuncTable.m_pfnMessageBox(g_pRadiantWnd,
					"Error: Couldn't find the triangle bounding a point.",
					"Decimation Error",MB_ICONEXCLAMATION, NULL);
				return;
			}
			if(!Tri[Node[i].tri].flag)
			{
				PlaneFromPoints(Node[Tri[Node[i].tri].v[0]].p,
				                Node[Tri[Node[i].tri].v[1]].p,
				                Node[Tri[Node[i].tri].v[2]].p,
								&Tri[Node[i].tri].plane);
				Tri[Node[i].tri].flag = 1;
			}
			Node[i].error =
				Node[i].p[j0] - (Tri[Node[i].tri].plane.dist -
							     Tri[Node[i].tri].plane.normal[j1]*Node[i].p[j1] -
								 Tri[Node[i].tri].plane.normal[j2]*Node[i].p[j2]  )/
								 Tri[Node[i].tri].plane.normal[j0];
			biggesterror = max(biggesterror,Absolute(Node[i].error));
		}
		if(biggesterror == 0)
			NumNodesToSave = NumNodesUsed;
		else
		{
			// For all current triangles, build a list of worst-case nodes
			memset(TriTable,0,NH*NV*2*sizeof(TRITABLE));
			for(i=0; i<NumNodes[0]; i++)
			{
				if(Node[i].used) continue;
				if(Absolute(Node[i].error) > TriTable[Node[i].tri].error)
				{
					TriTable[Node[i].tri].error = (float)(Absolute(Node[i].error));
					TriTable[Node[i].tri].node  = i;
				}
			}
			qsort( (void *)TriTable, (size_t)(NumTris[0]), sizeof(TRITABLE), (int (*)(const void *, const void *))compare );
			for(i=0; i<NumTris[0] && NumNodesUsed < NumNodesToSave && TriTable[i].error > 0.5*biggesterror; i++)
			{
				if(Node[TriTable[i].node].used) continue;  // shouldn't happen
				NumNodesUsed++;
				Node[TriTable[i].node].used++;
			}
			free(Tri);
			tricall(NumNodes[0], Node, NumTris, NULL, pTri, "cnzBNPY");
			Tri = *pTri;
			// Sliver-check along borders. Since borders are often linear, the errors
			// along borders will often be zero, so no new points will be added. This
			// tends to produce long, thin brushes. For all border triangles, check
			// that minimum angle isn't less than SLIVER_ANGLE. If it is, add another
			// vertex.
			while(CheckBorders(&NumNodesUsed,NumNodes[0],Node,NumTris,pTri) > 0)
			{
			}
			Tri = *pTri;
		}
	}
	free(TriTable);
	// One last time (because we're pessimistic), check border triangles
//	CheckBorders(&NumNodesUsed,NumNodes[0],Node,NumTris,pTri);
//	Tri = *pTri;

	// Check that all fixed points are exact. If not, add them to the mix.
	// First check to see if we have any fixed points that aren't already used.
	for(i=0, N=0; i<NumNodes[0] && !N; i++)
	{
		if(Node[i].used) continue;
		if(Node[i].fixed) N++;
	}
	if(N)
	{
		// Zero out the flag member of all triangles, indicating that
		// the plane equation has not been found.
		for(i=0; i<NumTris[0]; i++)
			Tri[i].flag = 0;

		for(i=0; i<NumNodes[0]; i++)
		{
			if(Node[i].used) continue;
			if(!Node[i].fixed) continue;
			Node[i].tri = -1;
			for(j=0; j<NumTris[0] && Node[i].tri==-1; j++)
			{
				if( side(Node[i].p[j1],          Node[i].p[j2],
					Node[Tri[j].v[0]].p[j1],Node[Tri[j].v[0]].p[j2],
					Node[Tri[j].v[1]].p[j1],Node[Tri[j].v[1]].p[j2]) < 0. ) continue;
				if( side(Node[i].p[j1],          Node[i].p[j2],
					Node[Tri[j].v[1]].p[j1],Node[Tri[j].v[1]].p[j2],
					Node[Tri[j].v[2]].p[j1],Node[Tri[j].v[2]].p[j2]) < 0. ) continue;
				if( side(Node[i].p[j1],          Node[i].p[j2],
					Node[Tri[j].v[2]].p[j1],Node[Tri[j].v[2]].p[j2],
					Node[Tri[j].v[0]].p[j1],Node[Tri[j].v[0]].p[j2]) < 0. ) continue;
				Node[i].tri = j;
			}
			if(Node[i].tri < 0)
			{
                          /*
				ghCursorCurrent = ghCursorDefault;
				SetCursor(ghCursorCurrent);
                          */
				g_FuncTable.m_pfnMessageBox(g_pRadiantWnd,
					"Error: Couldn't find the triangle bounding a point.",
					"Decimation Error",MB_ICONEXCLAMATION, NULL);
				return;
			}
			if(!Tri[Node[i].tri].flag)
			{
				PlaneFromPoints(Node[Tri[Node[i].tri].v[0]].p,
					            Node[Tri[Node[i].tri].v[1]].p,
				                Node[Tri[Node[i].tri].v[2]].p,
				                &Tri[Node[i].tri].plane);
				Tri[Node[i].tri].flag = 1;
			}
			Node[i].error =
				Node[i].p[j0] - (Tri[Node[i].tri].plane.dist -
				Tri[Node[i].tri].plane.normal[j1]*Node[i].p[j1] -
				Tri[Node[i].tri].plane.normal[j2]*Node[i].p[j2]  )/
				Tri[Node[i].tri].plane.normal[j0];
			if(Absolute(Node[i].error) > 0.5)
			{
				NumNodesUsed++;
				Node[i].used++;
				free(Tri);
				tricall(NumNodes[0], Node, NumTris, NULL, pTri, "cnzBNPY");
				Tri = *pTri;
			}
		}
	}

	// Swap node orders for surfaces facing down, north or west so that
	// they are counterclockwise when facing the surface

	if((Plane == PLANE_XY1) || (Plane == PLANE_XZ0) || (Plane == PLANE_YZ1) )
	{
		for(i=0; i<NumTris[0]; i++)
		{
			j = Tri[i].v[1];
			Tri[i].v[1] = Tri[i].v[2];
			Tri[i].v[2] = j;
		}
	}

	// Store bounding box coords
	for(i=0; i<NumTris[0]; i++)
	{
		Tri[i].min[0] =                   Node[Tri[i].v[0]].p[0];
		Tri[i].min[0] = min(Tri[i].min[0],Node[Tri[i].v[1]].p[0]);
		Tri[i].min[0] = min(Tri[i].min[0],Node[Tri[i].v[2]].p[0]);
		Tri[i].min[1] =                   Node[Tri[i].v[0]].p[1];
		Tri[i].min[1] = min(Tri[i].min[1],Node[Tri[i].v[1]].p[1]);
		Tri[i].min[1] = min(Tri[i].min[1],Node[Tri[i].v[2]].p[1]);
		Tri[i].min[2] =                   Node[Tri[i].v[0]].p[2];
		Tri[i].min[2] = min(Tri[i].min[2],Node[Tri[i].v[1]].p[2]);
		Tri[i].min[2] = min(Tri[i].min[2],Node[Tri[i].v[2]].p[2]);
		Tri[i].max[0] =                   Node[Tri[i].v[0]].p[0];
		Tri[i].max[0] = max(Tri[i].max[0],Node[Tri[i].v[1]].p[0]);
		Tri[i].max[0] = max(Tri[i].max[0],Node[Tri[i].v[2]].p[0]);
		Tri[i].max[1] =                   Node[Tri[i].v[0]].p[1];
		Tri[i].max[1] = max(Tri[i].max[1],Node[Tri[i].v[1]].p[1]);
		Tri[i].max[1] = max(Tri[i].max[1],Node[Tri[i].v[2]].p[1]);
		Tri[i].max[2] =                   Node[Tri[i].v[0]].p[2];
		Tri[i].max[2] = max(Tri[i].max[2],Node[Tri[i].v[1]].p[2]);
		Tri[i].max[2] = max(Tri[i].max[2],Node[Tri[i].v[2]].p[2]);
	}
        /*
	ghCursorCurrent = ghCursorDefault;
	SetCursor(ghCursorCurrent);
        */
}