Esempio n. 1
0
int CDanmakuCircleLine::Fire()
{
	for( int i = 0; i < n; ++i ) {
		double nn = (double)(n-1) / 2.0;
		double a;
		if( n != 0 )
			a = this->offset + w * (double)i/ n;
		else
			a = this->offset + 180;
		
		for ( int j = 0; j < m; ++j ) {
			CTama *p = pTama->Copy();
			if( m != 1 )
				p->v = this->sv + j * ( this->ev - this->sv ) / ( this->m - 1 );
			else
				p->v = this->sv;
			p->a = a;
			double xx = p->v * Cos( p->a ) + vv * Cos( aa );
			double yy = p->v * Sin( p->a ) + vv * Sin( aa );
			p->a = Atan2( xx, yy );
			p->v = sqrt( pow2( xx ) + pow2( yy ));
			g_lTama.Add( p );
		}
	}
	return 1;
}
Esempio n. 2
0
bool Quaternion::setLog(const Quaternion& q, int n)
{
	Real mag = q.norm();
	Real immag = q.imNorm();
	if(immag == Zero)
	{
		//there are infinitely (uncountably) many such logarithms, just choose the real case
		if(mag == Zero)
			return false;
		w = Log(mag);
		x = Zero;
		y = Zero;
		z = Zero;
	}
	else
	{
		Real immaginv = One / immag;
		Real arg = Atan2(immag, q.w) + Two*Pi*n;

		w = Log(mag);
		x = immaginv * arg * q.x;
		y = immaginv * arg * q.y;
		z = immaginv * arg * q.z;
	}
	return true;
}
void            co_XyzToEq(double xyz[], double *ra, double *dec)
  {
  double r,rho,x,y,z;
  x = xyz[0];
  y = xyz[1];
  z = xyz[2];
  rho = sqrt(x * x + y * y);
  r = sqrt(rho * rho + z * z);
  if (r < 1.0e-20)
    {
    *ra = 0.0;
    *dec = 0.0;
    }
  else
    {
    *ra = Atan2 (y,x) * 12.0 / M_PI;
    if (fabs(rho) > fabs(z))
      *dec = atan(z/rho) * 180.0 / M_PI;
    else
      {
      if (z > 0.0)
        *dec = 90.0 - atan(rho/z) * 180.0 / M_PI;
      else
        *dec = -90.0 - atan(rho/z) * 180.0 / M_PI;
      }
    }
  }
void SideStrafeGeneral(const PlayerData& player, const MovementVars& vars, bool onground, double wishspeed,
	const StrafeButtons& strafeButtons, bool useGivenButtons, Button& usedButton, double vel_yaw, double theta, bool right, Vector2D& velocity, double& yaw)
{
	if (useGivenButtons) {
		if (!onground) {
			if (right)
				usedButton = strafeButtons.AirRight;
			else
				usedButton = strafeButtons.AirLeft;
		} else {
			if (right)
				usedButton = strafeButtons.GroundRight;
			else
				usedButton = strafeButtons.GroundLeft;
		}
	} else {
		usedButton = GetBestButtons(theta, right);
	}
	double phi = ButtonsPhi(usedButton);
	theta = right ? -theta : theta;

	if (!player.Velocity.AsVector2D().IsZero(0))
		vel_yaw = Atan2(player.Velocity.y, player.Velocity.x);

	yaw = NormalizeRad(vel_yaw - phi + theta);

	Vector2D avec(std::cos(yaw + phi), std::sin(yaw + phi));
	PlayerData pl = player;
	VectorFME(pl, vars, onground, wishspeed, avec);
	velocity = pl.Velocity.AsVector2D();
}
Esempio n. 5
0
int CEnemyFairy16::Run()
{
	const v = 2;
	if( count < 60 ) {
		x -= v;
	}
	else if( count < 240 ) {
		if( count%10 == 0) {
			CTamaNormal tama;
			tama.x = GetX();
			tama.y = GetY();
			tama.type = 13;
			tama.color = 0;
			tama.v = 1.0 + 0.3 * GetDifficult();

			CDanmakuHorizon d(&tama);
			d.w = 1;
			if( GetDifficult() == DIFF_LUNATIC) {
				d.n = 4;
				d.m = 4;
			}else {
				d.n = 1 * ( GetDifficult() + 1 );
				d.m = 1 * ( GetDifficult() + 1 );
			}
			double angle = Atan2( g_pPlayer->GetX() - GetX(), g_pPlayer->GetY() - GetY());
			d.offset = angle + 360/d.m/4;
			d.Fire();
			g_pMaterial->sndFire.Play(0);
		}
	}
	else{
		x += v;
	}
	return CEnemyBase::Run();
}
Esempio n. 6
0
void HormingShot::update(Game* game) {
	Shot::update(game);
	accel += 0.2;

	const Vec2 targetPos = game->getNearEnemyPos();
	const double rad2 = Atan2(targetPos.y - pos.y, targetPos.x - pos.x);
	const double radLimit = Radians(10);
	if (count < TwoPi) {
		if (Abs(rad2 - rad) < radLimit) {
			rad = rad2;
			count += rad2;
		} else {
			if (rad2 < rad - Pi) {
				rad -= TwoPi;
			} else if (rad2 > rad + Pi) {
				rad += TwoPi;
			}
			if (rad2 < rad) {
				rad -= radLimit;
			} else {
				rad += radLimit;
			}
			count += radLimit;
		}
	}
	pos += Vec2(Cos(rad), Sin(rad)) * (10.0 + accel);

	tracks.push_front(pos);
	if (tracks.size() > 15) tracks.pop_back();
}
Esempio n. 7
0
int CDanmakuSegment::Fire()
{
	double vx1 = v1 * Cos( a1 );
	double vy1 = v1 * Sin( a1 );
	double vx2 = v2 * Cos( a2 );
	double vy2 = v2 * Sin( a2 );
	double nn = n - 1;
	double vx,vy;
	for( int i = 0; i < n; ++i ) {
		if( n != 1 ) {
			vx = vx1 * ( nn - i ) / nn + vx2 * i / nn;
			vy = vy1 * ( nn - i ) / nn + vy2 * i / nn;
		}
		else {
			vx = (vx1 + vx2)/2;
			vy = (vy1 + vy2)/2;
		}
		double vv = sqrt(pow2(vx) + pow2(vy));
		double aa = Atan2(vx,vy);
		CTama *p = pTama->Copy();
		p->v = pTama->v * vv;
		p->a = aa;
		g_lTama.Add( p );
	}
	return 1;
}
Esempio n. 8
0
Real HollowBall::closestPoint(const AxisSweptPoint& p) const
{
  Vector3 x,y;
  GetCanonicalBasis(p.axis.direction,x,y);
  Vector2 c2,p2,s2;
  c2.x = x.dot(center);
  c2.y = y.dot(center);
  p2.x = x.dot(p.p);
  p2.y = y.dot(p.p);
  s2.x = x.dot(p.axis.source);
  s2.y = y.dot(p.axis.source);
  c2-=s2;
  p2-=s2;
  Real ac = Atan2(c2.y,c2.x);
  Real ap = Atan2(p2.y,p2.x);
  return ac-ap;
}
Esempio n. 9
0
M_Real
M_VectorVecAngle2_FPU(M_Vector2 vOrig, M_Vector2 vOther)
{
	M_Vector2 vd;
	
	vd = M_VectorSub2p_FPU(&vOther, &vOrig);
	return (Atan2(vd.y, vd.x));
}
Esempio n. 10
0
/* Compute minimal distance from a circle to a point p. */
M_Real
M_CirclePointDistance2(M_Circle2 C, M_Vector2 p)
{
	M_Vector2 vR = M_VecSub2(p, C.p);
	M_Real theta = Atan2(vR.y, vR.x);

	return M_VecDistance2(p, M_VECTOR2(C.p.x + C.r*Cos(theta),
	                                   C.p.y + C.r*Sin(theta)));
}
Esempio n. 11
0
Quat::Quat(const Vec3f &V1,const Vec3f &V2,const Vec3f &V3)
{
	Quat	aQuat=Quat(V2,V1);

	Float	ang=Atan2(V1.x,V1.z);

	Quat	aQuat2=Quat(ang,V3);

	*this=aQuat*aQuat2;
}
double MaxAccelIntoYawTheta(const PlayerData& player, const MovementVars& vars, bool onground, double wishspeed, double vel_yaw, double yaw)
{
	if (!player.Velocity.AsVector2D().IsZero(0))
		vel_yaw = Atan2(player.Velocity.y, player.Velocity.x);

	double theta = MaxAccelTheta(player, vars, onground, wishspeed);
	if (theta == 0.0 || theta == M_PI)
		return NormalizeRad(yaw - vel_yaw + theta);
	return std::copysign(theta, NormalizeRad(yaw - vel_yaw));
}
Esempio n. 13
0
void Player::update(Game* game) {
	frameCount++;

	auto pad = XInput(0);
	pad.setLeftThumbDeadZone();
	pad.setRightThumbDeadZone();

	//move
	if (!Vec2(pad.leftThumbX, pad.leftThumbY).isZero) {
		rad = Atan2(-pad.leftThumbY, pad.leftThumbX);
		pos += Vec2(Cos(rad), Sin(rad)) * 7.5;
	}
	pos = Vec2(Clamp(pos.x, 0.0, static_cast<double>(Game::stageSize.x)), Clamp(pos.y, 0.0, static_cast<double>(Game::stageSize.y)));

	//bomb
	if (Input::KeyX.clicked) {
		game->getBulletManager()->clear();
		game->getEnemyManager()->clear();
	}

	//fire
	if (!Vec2(pad.rightThumbX, pad.rightThumbY).isZero) {
		for (int i : {-1, 1, 0}) {
			const double fireRad = Atan2(-pad.rightThumbY, pad.rightThumbX) + Radians(5 * i);
			if (fireCount % 5 == 0) {
				auto shot = std::make_shared<NormalShot>(pos, fireRad);
				shotManager->add(shot);
			}
		}
	}
	fireCount++;
	shotManager->update(game);

	tracks.push_front(pos);
	if (tracks.size() > 20) tracks.pop_back();

	damageCount++;
	checkBulletHit(game);
	if (frameCount % 10 == 0 && damageCount) shield++;
	shield = Clamp(shield, 0, SHIELD_MAX);
	hp = Clamp(hp, 0, HP_MAX);
}
Esempio n. 14
0
int CDanmakuCircleToPlayer::Fire()
{
	double angle = Atan2( g_pPlayer->GetX() - pTama->x, g_pPlayer->GetY() - pTama->y);
	for( int i = 0; i < n; ++i ) {
		double nn = (double)(n-1) / 2.0;
		double a;
		if( n != 0 )
			a = this->offset + w * (double)i/ n;
		else
			a = this->offset + 180;
		CTama *p = pTama->Copy();
		p->a = a;
		double xx = p->v * Cos( p->a ) + vv * Cos( aa + angle );
		double yy = p->v * Sin( p->a ) + vv * Sin( aa + angle );
		p->a = Atan2( xx, yy );
		p->v = sqrt( pow2( xx ) + pow2( yy ));
		g_lTama.Add( p );
	}
	return 1;
}
Esempio n. 15
0
int CDanmakuToPlayerRandom::Fire()
{
	double angle = Atan2( g_pPlayer->GetX() - pTama->x, g_pPlayer->GetY() - pTama->y);
	for( int i = 0; i < n; ++i ) {
		double a = angle + rand( -w, w ) + offset;
		double v = rand( sv, ev );
		CTama *p = pTama->Copy();
		p->a = a;
		p->v = v;
		g_lTama.Add( p );
	}
	return 1;
}
Esempio n. 16
0
void MiddleEnemy::update(Game* game) {
	Super::update(game);
	rad += Radians(10.0);

	const Vec2 playerPos = game->getPlayer()->getPos();
	const double rad2 = Atan2(playerPos.y - pos.y, playerPos.x - pos.x);

	if (frameCount % 100 < 50) {
		pos += Vec2(Cos(rad2), Sin(rad2)) * 3.0;
	} else if (frameCount % 3 == 0) {
		const double fireRad = rad2 + Radians(Random(-15.0, 15.0));
		auto bullet = std::make_shared<Bullet>(pos, Color(255, 100, 100), fireRad, Random(2.0, 7.0), 0.0);
		game->getBulletManager()->add(bullet);
	}
}
Esempio n. 17
0
static void
UpdateHue(AG_HSVPal *pal, int x, int y)
{
	float h;

	h = Atan2((float)y, (float)x);
	if (h < 0) {
		h += (float)(2*AG_PI);
	}
	AG_SetFloat(pal, "hue", h/(2*AG_PI)*360.0);

	UpdatePixelFromHSVA(pal);
	AG_PostEvent(NULL, pal, "h-changed", NULL);
	pal->flags |= AG_HSVPAL_DIRTY;
	AG_Redraw(pal);
}
Esempio n. 18
0
static float
PointProximity(void *p, VG_View *vv, VG_Vector *vPt)
{
	VG_Circle *vc = p;
	VG_Vector vCenter = VG_Pos(vc->p);
	float theta = Atan2(vPt->y - vCenter.y,
	                    vPt->x - vCenter.x);
	VG_Vector vNear;
	float d;

	vNear.x = vCenter.x + vc->r*Cos(theta);
	vNear.y = vCenter.y + vc->r*Sin(theta);
	d = VG_Distance(*vPt, vNear);
	*vPt = vNear;
	return (d);
}
Esempio n. 19
0
int CDanmakuToPlayer::Fire()
{
	double angle = Atan2( g_pPlayer->GetX() - pTama->x, g_pPlayer->GetY() - pTama->y);
	for( int i = 0; i < n; ++i ) {
		double m = (double)(n-1) / 2.0;
		double a;
		if( m != 0 )
			a = angle + w * ( (double)i -  m) / m;
		else
			a = angle;
		CTama *p = pTama->Copy();
		p->a = a;
		g_lTama.Add( p );
	}
	return 1;
}
double YawStrafeMaxAngle(PlayerData& player, const MovementVars& vars, bool onground, double wishspeed, const StrafeButtons& strafeButtons, bool useGivenButtons, Button& usedButton,
	double vel_yaw, double yaw)
{
	bool safeguard_yaw;
	double theta = MaxAngleTheta(player, vars, onground, wishspeed, safeguard_yaw);
	if (!player.Velocity.AsVector2D().IsZero(0.0f))
		vel_yaw = Atan2(player.Velocity[1], player.Velocity[0]);

	Vector2D newvel;
	double resulting_yaw;
	SideStrafeGeneral(player, vars, onground, wishspeed, strafeButtons, useGivenButtons, usedButton, vel_yaw, theta, (NormalizeRad(yaw - vel_yaw) < 0), newvel, resulting_yaw);

	if (safeguard_yaw) {
		Vector2D test_vel1, test_vel2;
		double test_yaw1, test_yaw2;

		SideStrafeGeneral(player, vars, onground, wishspeed, strafeButtons, useGivenButtons, usedButton, vel_yaw, min(theta - SAFEGUARD_THETA_DIFFERENCE_RAD, 0.0), (NormalizeRad(yaw - vel_yaw) < 0), test_vel1, test_yaw1);
		SideStrafeGeneral(player, vars, onground, wishspeed, strafeButtons, useGivenButtons, usedButton, vel_yaw, std::max(theta + SAFEGUARD_THETA_DIFFERENCE_RAD, 0.0), (NormalizeRad(yaw - vel_yaw) < 0), test_vel2, test_yaw2);

		double cos_test1 = test_vel1.Dot(player.Velocity.AsVector2D()) / (player.Velocity.Length2D() * test_vel1.Length());
		double cos_test2 = test_vel2.Dot(player.Velocity.AsVector2D()) / (player.Velocity.Length2D() * test_vel2.Length());
		double cos_newvel = newvel.Dot(player.Velocity.AsVector2D()) / (player.Velocity.Length2D() * newvel.Length());

		//DevMsg("cos_newvel = %.8f; cos_test1 = %.8f; cos_test2 = %.8f\n", cos_newvel, cos_test1, cos_test2);

		if (cos_test1 < cos_newvel) {
			if (cos_test2 < cos_test1) {
				newvel = test_vel2;
				resulting_yaw = test_yaw2;
				cos_newvel = cos_test2;
			} else {
				newvel = test_vel1;
				resulting_yaw = test_yaw1;
				cos_newvel = cos_test1;
			}
		} else if (cos_test2 < cos_newvel) {
			newvel = test_vel2;
			resulting_yaw = test_yaw2;
			cos_newvel = cos_test2;
		}
	} else {
		//DevMsg("theta = %.08f, yaw = %.08f, vel_yaw = %.08f, speed = %.08f\n", theta, yaw, vel_yaw, player.Velocity.Length2D());
	}

	player.Velocity.AsVector2D() = newvel;
	return resulting_yaw;
}
Esempio n. 21
0
void Quaternion::setPow(const Quaternion& q, Real n)
{
	Real mag = q.norm();
	Real immag = q.imNorm();
	Real immaginv;
	if(immag == Zero) immaginv = Zero;  //it's a real number, zero out the imaginary part
	else immaginv = One / immag;
	Real theta = Atan2(immag, q.w);

	Real cntheta = Cos(n*theta);
	Real sntheta = Sin(n*theta);
	Real powm = Pow(mag, n);

	w = powm * cntheta;
	x = powm * sntheta * immaginv * q.x;
	y = powm * sntheta * immaginv * q.y;
	z = powm * sntheta * immaginv * q.z;
}
Esempio n. 22
0
void AxisRotationFit(const std::vector<Vector3>& a,const std::vector<Vector3>& b,const Vector3& z,Real& theta)
{
  Assert(!a.empty());
  Assert(a.size()==b.size());
  //min sum||R*a[i]-b[i]||^2
  //  = sum (R*a[i]-b[i]).(R*a[i]-b[i])
  //  = sum a[i].a[i] + b[i].b[i] - 2 b[i].R*a[i]
  //differentiating, get
  //  0 = sum b[i].R'*a[i] = sum b[i].[z]R*a[i]
  //Let s=sin(theta) and c=cos(theta). 
  //  R = cI + (1-c)zz' + s[z]
  //so 
  //  0 = sum c*b[i]'[z]a[i] + (1-c)b[i]'[z]zz'a[i] + sb[i]'[z][z]a[i]
  //    = c*sum b[i]'[z]a[i] + s*b[i]'[z][z]a[i]
  // [z] = [0 -z y]
  //       [z 0 -x]
  //       [-y x 0]
  // [z]^2 = [-zz-yy  xy       xz   ]
  //         [xy     -xx-zz    yz   ]
  //         [xz      yz      -xx-yy]
  //collecting terms by s and c,
  //get s(sum -axbx-ayby) + c(sum axby-aybx) = 0
  //solve using theta = atan(sum axby-aybx / sum -axbx-ayby)
  //is it theta or theta+pi?
  Matrix3 zcross,zcross2;
  zcross.setCrossProduct(z);
  zcross2.mul(zcross,zcross);
  Real scoeff=0,ccoeff=0;
  for(size_t i=0;i<a.size();i++)
    scoeff += b[i].dot(zcross2*a[i]);
  for(size_t i=0;i<b.size();i++)
    ccoeff += b[i].dot(zcross*a[i]);

  if(FuzzyZero(scoeff) && FuzzyZero(ccoeff))
    theta=0;
  else 
    theta = Atan2(-ccoeff,scoeff);
   
  Real c=Cos(theta),s=Sin(theta);
  if(c*scoeff-s*ccoeff > 0) {
    theta += Pi;
  }
}
Esempio n. 23
0
void TransformCosSin_Sin(Real a,Real b,Real& c,Real& d)
{
  //use sin(x+d) = sin(x)cos(d) + cos(x)sin(d)
  //=> a=c*sin(d), b=c*cos(d)
  //=> c^2 = a^2+b^2
  if(a==0 && b==0) { c=d=0; }
  else {
    d = Atan2(a,b);
    c = pythag(a,b);
  }
  Real x=0.5;
  if(!FuzzyEquals(c*Sin(x+d),a*Cos(x)+b*Sin(x))) {
    printf("Error in TransformCosSin\n");
    printf("a: %f, b: %f\n",a,b);
    printf("c: %f, d: %f\n",c,d);
    printf("f(x): %f\n",a*Cos(x)+b*Sin(x));
    printf("g(x): %f\n",c*Sin(x+d));
  }
  Assert(FuzzyEquals(c*Sin(x+d),a*Cos(x)+b*Sin(x)));
}
Esempio n. 24
0
int CDanmakuToPlayerLine::Fire()
{
	double angle = offset + Atan2( g_pPlayer->GetX() - pTama->x, g_pPlayer->GetY() - pTama->y);
	for( int i = 0; i < n; ++i ) {
		double nn = (double)(n-1) / 2.0;
		double a;
		if( nn != 0 )
			a = angle + w * ( (double)i -  nn) / nn;
		else
			a = angle;
		for( int j = 0; j < m; ++j ) {
			CTama *p = pTama->Copy();
			if( m != 1 )
				p->v = this->sv + j * ( this->ev - this->sv ) / ( this->m - 1 );
			else
				p->v = this->sv;
			p->a = a;
			g_lTama.Add( p );
		}
	}
	return 1;
}
Esempio n. 25
0
int CDanmakuSegmentLine::Fire()
{
	double vx1 = v1 * Cos( a1 );
	double vy1 = v1 * Sin( a1 );
	double vx2 = v2 * Cos( a2 );
	double vy2 = v2 * Sin( a2 );
	double nn = n - 1;
	for( int i = 0; i < n; ++i ) {
		double vx = vx1 * i / nn + vx2 * ( nn - i ) / nn;
		double vy = vy1 * i / nn + vy2 * ( nn - i ) / nn;
		double vv = sqrt(pow2(vx) + pow2(vy));
		double aa = Atan2(vx,vy);
		for( int j = 0; j < m; ++j ) {
			CTama *p = pTama->Copy();
			if( m == 1 )
				p->v = vv;
			else
				p->v = vv * j / (m-1) + vv * ev * (m-1-j) / (m-1);
			p->a = aa;
			g_lTama.Add( p );
		}
	}
	return 1;
}
Esempio n. 26
0
void curve4_div::recursive_bezier(scalar x1, scalar y1, scalar x2, scalar y2, scalar x3, scalar y3, scalar x4, scalar y4, unsigned int level)
{
    if (level > curve_recursion_limit) {
        return;
    }

    // Calculate all the mid-points of the line segments
    //----------------------
    scalar x12   = (x1 + x2) / 2;
    scalar y12   = (y1 + y2) / 2;
    scalar x23   = (x2 + x3) / 2;
    scalar y23   = (y2 + y3) / 2;
    scalar x34   = (x3 + x4) / 2;
    scalar y34   = (y3 + y4) / 2;
    scalar x123  = (x12 + x23) / 2;
    scalar y123  = (y12 + y23) / 2;
    scalar x234  = (x23 + x34) / 2;
    scalar y234  = (y23 + y34) / 2;
    scalar x1234 = (x123 + x234) / 2;
    scalar y1234 = (y123 + y234) / 2;


    // Try to approximate the full cubic curve by a single straight line
    //------------------
    scalar dx = x4-x1;
    scalar dy = y4-y1;

    scalar d2 = Fabs(((x2 - x4) * dy - (y2 - y4) * dx));
    scalar d3 = Fabs(((x3 - x4) * dy - (y3 - y4) * dx));
    scalar da1, da2, k;

    switch((int(d2 > curve_collinearity_epsilon) << 1) + int(d3 > curve_collinearity_epsilon))
    {
    case 0:
        // All collinear OR p1==p4
        //----------------------
        k = dx*dx + dy*dy;
        if (k == 0) {
            d2 = calc_sq_distance(x1, y1, x2, y2);
            d3 = calc_sq_distance(x4, y4, x3, y3);
        } else {
            k   = 1 / k;
            da1 = x2 - x1;
            da2 = y2 - y1;
            d2  = k * (da1*dx + da2*dy);
            da1 = x3 - x1;
            da2 = y3 - y1;
            d3  = k * (da1*dx + da2*dy);
            if (d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1) {
                // Simple collinear case, 1---2---3---4
                // We can leave just two endpoints
                return;
            }

            if (d2 <= 0)
                d2 = calc_sq_distance(x2, y2, x1, y1);
            else if(d2 >= 1)
                d2 = calc_sq_distance(x2, y2, x4, y4);
            else
                d2 = calc_sq_distance(x2, y2, x1 + d2*dx, y1 + d2*dy);

            if (d3 <= 0)
                d3 = calc_sq_distance(x3, y3, x1, y1);
            else if(d3 >= 1)
                d3 = calc_sq_distance(x3, y3, x4, y4);
            else
                d3 = calc_sq_distance(x3, y3, x1 + d3*dx, y1 + d3*dy);
        }

        if (d2 > d3) {
            if (d2 < m_distance_tolerance_square) {
                m_points.add(vertex_s(x2, y2));
                return;
            }
        } else {
            if (d3 < m_distance_tolerance_square) {
                m_points.add(vertex_s(x3, y3));
                return;
            }
        }
        break;

    case 1:
        // p1,p2,p4 are collinear, p3 is significant
        //----------------------
        if (d3 * d3 <= m_distance_tolerance_square * (dx*dx + dy*dy)) {
            if (m_angle_tolerance < curve_angle_tolerance_epsilon) {
                m_points.add(vertex_s(x23, y23));
                return;
            }

            // Angle Condition
            //----------------------
            da1 = Fabs(Atan2(y4 - y3, x4 - x3) - Atan2(y3 - y2, x3 - x2));
            if (da1 >= PI)
                da1 = _2PI - da1;

            if (da1 < m_angle_tolerance) {
                m_points.add(vertex_s(x2, y2));
                m_points.add(vertex_s(x3, y3));
                return;
            }

            if (m_cusp_limit != 0.0) {
                if (da1 > m_cusp_limit) {
                    m_points.add(vertex_s(x3, y3));
                    return;
                }
            }
        }
        break;

    case 2:
        // p1,p3,p4 are collinear, p2 is significant
        //----------------------
        if (d2 * d2 <= m_distance_tolerance_square * (dx*dx + dy*dy)) {
            if (m_angle_tolerance < curve_angle_tolerance_epsilon) {
                m_points.add(vertex_s(x23, y23));
                return;
            }

            // Angle Condition
            //----------------------
            da1 = Fabs(Atan2(y3 - y2, x3 - x2) - Atan2(y2 - y1, x2 - x1));
            if (da1 >= PI)
                da1 = _2PI - da1;

            if (da1 < m_angle_tolerance) {
                m_points.add(vertex_s(x2, y2));
                m_points.add(vertex_s(x3, y3));
                return;
            }

            if (m_cusp_limit != 0.0) {
                if (da1 > m_cusp_limit) {
                    m_points.add(vertex_s(x2, y2));
                    return;
                }
            }
        }
        break;

    case 3:
        // Regular case
        //-----------------
        if ((d2 + d3)*(d2 + d3) <= m_distance_tolerance_square * (dx*dx + dy*dy)) {
            // If the curvature doesn't exceed the distance_tolerance value
            // we tend to finish subdivisions.
            //----------------------
            if (m_angle_tolerance < curve_angle_tolerance_epsilon) {
                m_points.add(vertex_s(x23, y23));
                return;
            }

            // Angle & Cusp Condition
            //----------------------
            k   = Atan2(y3 - y2, x3 - x2);
            da1 = Fabs(k - Atan2(y2 - y1, x2 - x1));
            da2 = Fabs(Atan2(y4 - y3, x4 - x3) - k);
            if (da1 >= PI)
                da1 = _2PI - da1;
            if (da2 >= PI)
                da2 = _2PI - da2;

            if (da1 + da2 < m_angle_tolerance) {
                // Finally we can stop the recursion
                //----------------------
                m_points.add(vertex_s(x23, y23));
                return;
            }

            if (m_cusp_limit != 0.0) {
                if (da1 > m_cusp_limit) {
                    m_points.add(vertex_s(x2, y2));
                    return;
                }

                if (da2 > m_cusp_limit) {
                    m_points.add(vertex_s(x3, y3));
                    return;
                }
            }
        }
        break;
    }

    // Continue subdivision
    //----------------------
    recursive_bezier(x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1);
    recursive_bezier(x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1);
}
Esempio n. 27
0
inline Base<F> Arg( const F& alpha )
{ return Atan2( ImagPart(alpha), RealPart(alpha) ); }
Esempio n. 28
0
 static int calculate(int x, int y, int d)
 {
     scalar a = Atan2(INT_TO_SCALAR(y), INT_TO_SCALAR(x));
     if (a < 0) a = _2PI + a;
     return iround(a * INT_TO_SCALAR(d) * _1div2PI);
 }
Esempio n. 29
0
 static int calculate(int x, int y, int d)
 {
     return uround(Fabs(Atan2(INT_TO_SCALAR(y), INT_TO_SCALAR(x))) * INT_TO_SCALAR(d) * _1divPI);
 }
Esempio n. 30
0
//------------------------------------------------------------------------
void curve3_div::recursive_bezier(scalar x1, scalar y1, scalar x2, scalar y2, scalar x3, scalar y3, unsigned int level)
{
    if (level > curve_recursion_limit) {
        return;
    }

    // Calculate all the mid-points of the line segments
    //----------------------
    scalar x12   = (x1 + x2) / 2;
    scalar y12   = (y1 + y2) / 2;
    scalar x23   = (x2 + x3) / 2;
    scalar y23   = (y2 + y3) / 2;
    scalar x123  = (x12 + x23) / 2;
    scalar y123  = (y12 + y23) / 2;

    scalar dx = x3-x1;
    scalar dy = y3-y1;
    scalar d = Fabs(((x2 - x3) * dy - (y2 - y3) * dx));
    scalar da;

    if (d > curve_collinearity_epsilon) {
        // Regular case
        //-----------------
        if (d * d <= m_distance_tolerance_square * (dx*dx + dy*dy)) {
            // If the curvature doesn't exceed the distance_tolerance value
            // we tend to finish subdivisions.
            //----------------------
            if (m_angle_tolerance < curve_angle_tolerance_epsilon) {
                m_points.add(vertex_s(x123, y123));
                return;
            }

            // Angle & Cusp Condition
            //----------------------
            da = Fabs(Atan2(y3 - y2, x3 - x2) - Atan2(y2 - y1, x2 - x1));
            if (da >= PI)
                da = _2PI - da;

            if (da < m_angle_tolerance) {
                // Finally we can stop the recursion
                //----------------------
                m_points.add(vertex_s(x123, y123));
                return;
            }
        }
    } else {
        // Collinear case
        //------------------
        da = dx*dx + dy*dy;
        if (da == 0) {
            d = calc_sq_distance(x1, y1, x2, y2);
        } else {
            d = ((x2 - x1)*dx + (y2 - y1)*dy) / da;
            if (d > 0 && d < 1) {
                // Simple collinear case, 1---2---3
                // We can leave just two endpoints
                return;
            }

            if (d <= 0)
                d = calc_sq_distance(x2, y2, x1, y1);
            else if (d >= 1)
                d = calc_sq_distance(x2, y2, x3, y3);
            else
                d = calc_sq_distance(x2, y2, x1 + d*dx, y1 + d*dy);
        }

        if (d < m_distance_tolerance_square) {
            m_points.add(vertex_s(x2, y2));
            return;
        }
    }

    // Continue subdivision
    //----------------------
    recursive_bezier(x1, y1, x12, y12, x123, y123, level + 1);
    recursive_bezier(x123, y123, x23, y23, x3, y3, level + 1);
}