Beispiel #1
0
float mglnrel::ptToBeeline2(
    const Point2d& a, const Point2d& b, const Point2d& pt, Point2d& ptPerp)
{
    // 两点重合
    if (a == b)
    {
        ptPerp = a;
        return a.distanceTo(pt);
    }
    // 竖直线
    else if (mgEquals(a.x, b.x))
    {
        ptPerp.set(a.x, pt.y);
        return fabsf(a.x - pt.x);
    }
    // 水平线
    else if (mgEquals(a.y, b.y))
    {
        ptPerp.set(pt.x, a.y);
        return fabsf(a.y - pt.y);
    }
    else
    {
        float t1 = ( b.y - a.y ) / ( b.x - a.x );
        float t2 = -1.f / t1;
        ptPerp.x = ( pt.y - a.y + a.x * t1 - pt.x * t2 ) / ( t1 - t2 );
        ptPerp.y = a.y + (ptPerp.x - a.x) * t1;
        return pt.distanceTo(ptPerp);
    }
}
Beispiel #2
0
// http://blog.csdn.net/cyg0810/article/details/7765894
int mgcurv::crossTwoCircles(Point2d& pt1, Point2d& pt2,
                            const Point2d& c1, float r1, const Point2d& c2, float r2)
{
    point_t p1, p2;
    point_t ca(c1.x, c1.y);
    point_t cb(c2.x, c2.y);
    int n = _crossTwoCircles(p1, p2, ca, r1, cb, r2);
    
    pt1.set((float)p1.x, (float)p1.y);
    pt2.set((float)p2.x, (float)p2.y);
    
    return n;
}
 virtual bool load(MgStorage* s) {
     pt.set(s->readFloat("x", pt.x), s->readFloat("y", pt.y));
     vec.set(s->readFloat("w", vec.x), s->readFloat("h", vec.y));
     stroke = s->readBool("stroke", stroke);
     fill = s->readBool("fill", fill);
     return true;
 }
Beispiel #4
0
void Game::SpectatorsCheers(){
	Point2d corner;
	// The cheering will last for 2 seconds
	if (clock() - cheer_start < 2000 && cheer_start != 0){
		frames_to_cheer++;
		if (frames_to_cheer == FRAMES_TO_CHEER_LIMIT){
			// The changes of colors for the spectators will 
			// happen once on FRAMES_TO_CHEER_LIMIT frames, 
			// which in our case is 10
			(m_last_scored == 0)?corner.set(-21.0f, 16.5f):corner.set(-21.0f, -1.0f);
			RemoveSpectators(m_last_scored);
			DrawSpectators(corner, m_last_scored);
			frames_to_cheer = 0;
		}
	}
}
Beispiel #5
0
void Game::DrawSpectators(Point2d corner, int team){
	const int columns = 5; 
	int rows = 14;
	Circle spectator(10, SPECTATOR_CIRCLE_RAY);
	float randr, randg;
	for(int i=0; i < columns; ++i){
		corner.set(corner.x + SPECTATOR_CIRCLE_RAY*2 + 0.1f,
					corner.y - SPECTATOR_CIRCLE_RAY*2 + 0.43f);
		for(int j=0; j < rows; ++j){
			if (team == 0){
				randr = (float)rand()/(3*RAND_MAX);
				randg = (float)rand()/RAND_MAX;
				spectator.SetColor(RGBcolor(randr, randg, 1.0f));
			}
			else if (team == 1){
				randg = (float)rand()/RAND_MAX; 
				spectator.SetColor(RGBcolor(1.0f, randg, 0.09f));
			}
			spectator.DrawCircle(m_system, Point2d(corner.x, 
					corner.y - (SPECTATOR_CIRCLE_RAY*2 + 0.1f)*j));
			if (team == 0){
				spectators1.push_back(spectator.GetObject());
			}
			else {
				spectators2.push_back(spectator.GetObject());
			}
		}
		rows--;
	}
}
Beispiel #6
0
int mgcurv::crossLineCircle(Point2d& pt1, Point2d& pt2, const Point2d& a,
                            const Point2d& b, const Point2d& c, float r)
{
    if (a == b) {
        return 0;
    }
    
    point_t p1, p2;
    point_t a1(a.x - c.x, a.y - c.y);
    point_t b1(b.x - c.x, b.y - c.y);
    int n = _crossLineCircle(p1, p2, a1, b1, r);
    
    pt1.set((float)p1.x + c.x, (float)p1.y + c.y);
    pt2.set((float)p2.x + c.x, (float)p2.y + c.y);
    
    return n;
}
/**
 * calculate if this line intersects with the provided Line l
 * Point2d * intersection output of the intersection point
 */
bool Line::intersect( const Line* l, Point2d & intersection ) {
  const Line* p, *q;
  /* compare length of lines and assign pointers */
  if( this->length() < l->length() ) {
    p = l;
    q = this;
  }
  else {
    p = this;
    q = l;
  } /* p is now the line longer or the same length then q */

  float ccwpa = p->ccw( q->getA() );
  float ccwpb = p->ccw( q->getB() );
  float ccwqa = q->ccw( p->getA() );
  float ccwqb = q->ccw( p->getB() );

  /* check collinearity of the two lines */
  if( fabs( ccwpa ) <= FLT_EPSILON && fabs( ccwpb ) <= FLT_EPSILON ) { /* lines are collinear */
    return false; /* if they are collinear, just return false. */
  }

  /* lines are not collinear -> check for intersection or(!) contact */
  if( ( ( ccwpa * ccwpb ) <= FLT_EPSILON )
      && ( ( ccwqa * ccwqb ) <= FLT_EPSILON ) ) {

    //calculate the point
    float den = ( p->getA().getX() - p->getB().getX() )
        * ( q->getA().getY() - q->getB().getY() )
        - ( p->getA().getY() - p->getB().getY() )
            * ( q->getA().getX() - q->getB().getX() );

    if( fabs( den ) <= FLT_EPSILON )
      return false;

    float x = ( ( p->getA().getX() * p->getB().getY()
        - p->getA().getY() * p->getB().getX() )
        * ( q->getA().getX() - q->getB().getX() )
        - ( p->getA().getX() - p->getB().getX() )
            * ( q->getA().getX() * q->getB().getY()
                - q->getA().getY() * q->getB().getX() ) ) / den;

    float y = ( ( p->getA().getX() * p->getB().getY()
        - p->getA().getY() * p->getB().getX() )
        * ( q->getA().getY() - q->getB().getY() )
        - ( p->getA().getY() - p->getB().getY() )
            * ( q->getA().getX() * q->getB().getY()
                - q->getA().getY() * q->getB().getX() ) ) / den;
    intersection.set( x, y );

    return true;
  }

  return false;
}
Beispiel #8
0
bool GiTransform::zoomScale(float viewScale, const Point2d* pxAt, bool adjust)
{
    // 检查显示比例
    if (!adjust && ScaleOutRange(viewScale, m_impl))
        return false;
    viewScale = mgMax(viewScale, m_impl->minViewScale);
    viewScale = mgMin(viewScale, m_impl->maxViewScale);

    // 得到放缩中心点的客户区坐标
    Point2d ptAt (m_impl->cxWnd * 0.5f,  m_impl->cyWnd * 0.5f);
    if (pxAt != NULL)
        ptAt.set(pxAt->x, pxAt->y);

    // 得到放缩中心点在放缩前的世界坐标
    Point2d ptAtW (ptAt * m_impl->matD2W);

    // 计算新显示比例下显示窗口中心的世界坐标
    Point2d ptW;
    float w2dx = m_impl->w2dx / m_impl->viewScale * viewScale;
    float w2dy = m_impl->w2dy / m_impl->viewScale * viewScale;
    ptW.x = ptAtW.x + (m_impl->cxWnd * 0.5f - ptAt.x) / w2dx;
    ptW.y = ptAtW.y - (m_impl->cyWnd * 0.5f - ptAt.y) / w2dy;

    // 检查新显示比例下显示窗口的世界坐标范围是否在极限范围内
    float halfw = m_impl->cxWnd / w2dx * 0.5f;
    float halfh = m_impl->cyWnd / w2dy * 0.5f;
    Box2d box (ptW, 2 * halfw, 2 * halfh);

    if (!AdjustCenterIn(adjust, box, m_impl->rectLimitsW, ptW, halfw, halfh)) {
        return false;
    }
    if (halfw - 3 > m_impl->rectLimitsW.width() / 2
        && halfh - 3 > m_impl->rectLimitsW.height() / 2)    // 显示比例太小
    {
        viewScale *= mgMin(2 * (halfw - 3) / m_impl->rectLimitsW.width(),
            2 * (halfh - 3) / m_impl->rectLimitsW.height());
        viewScale = mgMin(viewScale, m_impl->maxViewScale);
    }

    return m_impl->zoomNoAdjust(ptW, viewScale);
}
Beispiel #9
0
bool GiTransform::zoomScale(float viewScale, const Point2d* pxAt, bool adjust)
{
    // 检查显示比例
    if (!adjust && ScaleOutRange(viewScale, m_impl))
        return false;
    viewScale = mgMax(viewScale, m_impl->minViewScale);
    viewScale = mgMin(viewScale, m_impl->maxViewScale);

    // 得到放缩中心点的客户区坐标
    Point2d ptAt (m_impl->cxWnd * 0.5f,  m_impl->cyWnd * 0.5f);
    if (pxAt != NULL)
        ptAt.set(pxAt->x, pxAt->y);

    // 得到放缩中心点在放缩前的世界坐标
    Point2d ptAtW (ptAt * m_impl->matD2W);

    // 计算新显示比例下显示窗口中心的世界坐标
    Point2d ptW;
    float w2dx = m_impl->w2dx / m_impl->viewScale * viewScale;
    float w2dy = m_impl->w2dy / m_impl->viewScale * viewScale;
    ptW.x = ptAtW.x + (m_impl->cxWnd * 0.5f - ptAt.x) / w2dx;
    ptW.y = ptAtW.y - (m_impl->cyWnd * 0.5f - ptAt.y) / w2dy;

    // 检查新显示比例下显示窗口的世界坐标范围是否在极限范围内
    float halfw = m_impl->cxWnd / w2dx * 0.5f;
    float halfh = m_impl->cyWnd / w2dy * 0.5f;
    Box2d box (ptW, 2 * halfw, 2 * halfh);
    if (!m_impl->rectLimitsW.isEmpty() && !m_impl->rectLimitsW.contains(box))
    {
        if (adjust)
            AdjustCenterW(ptW, halfw, halfh, m_impl->rectLimitsW);
        else
            return false;
    }

    return m_impl->zoomNoAdjust(ptW, viewScale);
}
Beispiel #10
0
bool GiTransform::zoomTo(const Box2d& rectWorld, const RECT_2D* rcTo, bool adjust)
{
    // 如果图形范围的宽或高接近于零,就返回
    if (rectWorld.isEmpty())
        return false;

    // 计算像素到毫米的比例
    const float d2mmX = m_impl->viewScale / m_impl->w2dx;
    const float d2mmY = m_impl->viewScale / m_impl->w2dy;

    // 计算目标窗口区域(毫米)
    float w = 0, h = 0;
    Point2d ptCen;

    if (rcTo != NULL) {
        w = fabsf(static_cast<float>(rcTo->right - rcTo->left));
        h = fabsf(static_cast<float>(rcTo->bottom - rcTo->top));
        ptCen.x = (rcTo->left + rcTo->right) * 0.5f;
        ptCen.y = (rcTo->top + rcTo->bottom) * 0.5f;
    }
    if (w < 4 || h < 4) {
        w = (float)m_impl->cxWnd;
        h = (float)m_impl->cyWnd;
        ptCen.set(w * 0.5f, h * 0.5f);
        w -= 8;
        h -= 8;
    }
    if (w < 4 || h < 4)
        return false;
    w *= d2mmX;
    h *= d2mmY;
    ptCen.scaleBy(d2mmX, d2mmY);

    // 计算新显示比例 (中心不变,缩小窗口区域使得宽高比例和图形范围相同)
    float scale;
    if (h * rectWorld.width() > w * rectWorld.height()) {
        //h = w * rectWorld.height() / rectWorld.width();
        scale = w / rectWorld.width();
    }
    else {
        //w = h * rectWorld.width() / rectWorld.height();
        scale = h / rectWorld.height();
    }

    // 检查显示比例
    if (!adjust && ScaleOutRange(scale, m_impl))
        return false;
    scale = mgMax(scale, m_impl->minViewScale);
    scale = mgMin(scale, m_impl->maxViewScale);

    // 计算在新显示比例下显示窗口中心的世界坐标
    Point2d ptW;
    ptW.x = rectWorld.center().x + (m_impl->cxWnd * d2mmX * 0.5f - ptCen.x) / scale;
    ptW.y = rectWorld.center().y - (m_impl->cyWnd * d2mmY * 0.5f - ptCen.y) / scale;

    // 检查新显示比例下显示窗口的世界坐标范围是否在极限范围内
    float halfw = m_impl->cxWnd * d2mmX  / scale * 0.5f;
    float halfh = m_impl->cyWnd * d2mmY  / scale * 0.5f;
    Box2d box (ptW, 2 * halfw, 2 * halfh);

    if (!AdjustCenterIn(adjust, box, m_impl->rectLimitsW, ptW, halfw, halfh)) {
        return false;
    }

    return m_impl->zoomNoAdjust(ptW, scale);
}
Beispiel #11
0
void Matrix2d::getCoordSystem(Vector2d& e0, Vector2d& e1, Point2d& origin) const
{
    e0.set(m11, m12);
    e1.set(m21, m22);
    origin.set(dx, dy);
}
 virtual bool load(MgStorage* s) {
     pt.set(s->readFloat("x", pt.x), s->readFloat("y", pt.y));
     vec.set(s->readFloat("w", vec.x), s->readFloat("h", vec.y));
     return true;
 }
 virtual bool load(MgStorage* s) {
     pt1.set(s->readFloat("x1", pt1.x), s->readFloat("y1", pt1.y));
     pt2.set(s->readFloat("x2", pt2.x), s->readFloat("y2", pt2.y));
     return true;
 }