예제 #1
0
/**
 * Der Winkel zur Z-Achse bei Rotation um Y-Achse
 * @return der Winkel, um den der Vektor um die Y-Achse rotiert werden müsste, um zur Z-Achse koliniar zu sein.
 */
GLdouble SGLVektor::Ywink()
{
	GLdouble teiler=sqrt(SGLV_X*SGLV_X+SGLV_Z*SGLV_Z);
	if(SGLV_X>=0)
	{
		if(SGLV_Z>=0)return ACOS(SGLV_X/teiler);
		else return 360-ACOS(SGLV_X/teiler);
	}
	else
	{
		if(SGLV_Z>=0)return 180-ACOS(SGLV_X/teiler);
		else return 180+ACOS(SGLV_X/teiler);
	}
}
예제 #2
0
/**
 * Der Winkel zu Z-Achse bei Rotation um X-Achse
 * @return der Winkel, um den der Vektor um die X-Achse rotiert werden müsste, um zur Z-Achse koliniar zu sein.
 */
GLdouble SGLVektor::Xwink()
{
	GLdouble teiler=sqrt(SGLV_Z*SGLV_Z+SGLV_Y*SGLV_Y);
	if(SGLV_Z>=0)
	{
		if(SGLV_Y>=0)return ACOS(SGLV_Z/teiler);
		else return 360-ACOS(SGLV_Z/teiler);
	}
	else
	{
		if(SGLV_Y>=0)return 180-ACOS(SGLV_Z/teiler);
		else return 180+ACOS(SGLV_Z/teiler);
	}
	return 0;
}
예제 #3
0
파일: Line.cpp 프로젝트: vinceplusplus/z3D
		bool Line::isParallel(const Line& l,REAL biasAngle) const
		{
			REAL a=ACOS(FABS((p[0]-p[1]).normal()*(l[0]-p[1]).normal()));
			if(a<=biasAngle)
				return true;
			return false;
		}
예제 #4
0
	Int32 Cubic( Real x3, Real x2, Real x, Real k, Real roots[3] )
	{
		if( IsZero( x3 ) )
			return Quadratic( x2, x, k, roots );

		Real a, b, c, d, a2, p, q, p3, s;

		// Normalize
		a = x2 / x3;
		b = x  / x3;
		c = k  / x3;

		// Reduction to a depressed cubic
		a2 = a * a;
		p = 1.0f / 3.0f * ( -1.0f / 3.0f * a2 + b );
		q = 1.0f / 2.0f * ( 2.0f / 27.0f * a * a2 - 1.0f / 3.0f * a * b + c );
		s = 1.0f / 3.0f * a;

		// Cardano's method
		p3 = p * p * p;
		d = q * q + p3;

		if( IsZero( d ) )
		{
			if( IsZero( q ) )
			{
				roots[0] = -s;
				return 1;			
			}
			else
			{
				Real u = CubeRoot( -q );
				roots[0] = 2.0f * u - s;
				roots[1] = -u - s;
				return 2;
			}
		}

		if( d < 0.0f )
		{
			Real phi = 1.0f / 3.0f * ACOS( -q / SQRT( -p3 ) );
			Real t = 2.0f * SQRT( -p );
			roots[0] =  t * COS( phi ) - s;
			roots[1] = -t * COS( phi + PI / 3.0f ) - s;
			roots[2] = -t * COS( phi - PI / 3.0f ) - s;
			return 3;
		}

		Real u = CubeRoot( SQRT( d ) + ABS( q ) );
		roots[0] = ( q > 0.0f ? - u + p / u : u - p / u ) - s;
		return 1;
	}
예제 #5
0
void AstroClock::convert(uint32_t timestamp, float ra, float dec, float* alt,
		float* az) {
	float lstd = getLSTd(convertJ2000(timestamp));
	float ha = lstd - ra;
	while (ha < 0)
		ha += 360.0;

	float sinAlt = SIN(dec) * SIN(lat) + COS(dec) * COS(lat) * COS(ha);
	*alt = ASIN(sinAlt);

	float cosA = //
			(SIN(dec) - SIN(*alt) * SIN(lat)) //
			/ (COS(*alt) * COS(lat));

	float a = ACOS(cosA);

	if (SIN(ha) < 0)
		*az = a;
	else
		*az = 360.0 - a;
}
예제 #6
0
파일: gelinint.c 프로젝트: mildred/Varkon
        DBstatus GE706(
        DBAny  *pstr1,
        DBAny  *pstr2,
        short  *noint,
        DBfloat u1[],
        DBfloat u2[])

/*      Compute intersect between line and arc/circle in 2D.
 *
 *      In: pstr1  => First entity
 *          pstr2  => Second entity
 *          noint  => Requested solution +/-
 *
 *      Out: *noint => Number of solutions
 *           *u1    => Parametric values related to the line
 *           *u2    => Parameteric values related to the arc
 *
 *      (C)microform ab  5/8/85 R. Svedin efter IVAR
 *
 *       12/8/85  Anpassning till v3, J.Kjellander
 *       3/1/86   Tangering, J. Kjellander
 *       15/1/86  Bug lodrät linje, J. Kjellander
 *       13/4/86  Bytt TOL1 mot TOL2, J. Kjellander
 *       19/4/86  Horisontell linje, J. Kjellander
 *       26/11/89 Neg intnr, J. Kjellander
 *       1999-05-10 Rewritten, J.Kjellander
 *
 ******************************************************************!*/

  {
   DBLine *linpek;
   DBArc  *arcpek;
   DBfloat k,k2,p,q,dx,dy;
   DBfloat x1,y1,x2,y2,tt,tmp;
   DBfloat t1[2],t2[2];
   short   i;

/*
***Which is which ?
*/
   if ( pstr1->hed_un.type == LINTYP )
      {
      linpek = (GMLIN *)pstr1;
      arcpek = (GMARC *)pstr2;
      }
   else
      {
      linpek = (GMLIN *)pstr2;
      arcpek = (GMARC *)pstr1;
      }
/*
***Some init.
*/
   dx = linpek->crd2_l.x_gm - linpek->crd1_l.x_gm;
   dy = linpek->crd2_l.y_gm - linpek->crd1_l.y_gm;
/*
***Vertical, horisontal or sloping line ?
*
***Horisontal.
*/
   if ( ABS(dx) > 1000.0*ABS(dy) )
      {
      if ( ABS(linpek->crd1_l.y_gm-arcpek->y_a)-arcpek->r_a  > TOL2 )
         {
         *noint = 0;
         return(0);
         }

      y1 = y2 = linpek->crd1_l.y_gm;

      if ( arcpek->r_a > ABS(linpek->crd1_l.y_gm-arcpek->y_a) )
        {
        x1 = arcpek->x_a + arcpek->r_a*COS(ASIN((linpek->
             crd1_l.y_gm-arcpek->y_a)/arcpek->r_a));
        x2 = 2.0*arcpek->x_a - x1;
        }
      else
        {
        x1 = x2 = arcpek->x_a;
        }

      t1[0] = 1.0 + (x1 - linpek->crd1_l.x_gm) / dx;
      t1[1] = 1.0 + (x2 - linpek->crd1_l.x_gm) / dx;
      }
/*
***Vertical.
*/
   else if ( ABS(dy) > 1000.0*ABS(dx) )
      {
      if ( ABS(linpek->crd1_l.x_gm-arcpek->x_a)-arcpek->r_a  > TOL2 )
         {
         *noint = 0;
         return(0);
         }

      x1 = x2 = linpek->crd1_l.x_gm;

      if ( arcpek->r_a > ABS(linpek->crd1_l.x_gm-arcpek->x_a) )
        {
        y1 = arcpek->y_a + arcpek->r_a*SIN(ACOS((linpek->
             crd1_l.x_gm-arcpek->x_a)/arcpek->r_a));
        y2 = 2.0*arcpek->y_a - y1;
        }
      else
        {
        y1 = y2 = arcpek->y_a;
        }

      t1[0] = 1.0 + (y1 - linpek->crd1_l.y_gm) / dy;
      t1[1] = 1.0 + (y2 - linpek->crd1_l.y_gm) / dy;
      }
/*
***Sloping.
*/
   else
      {
      k  = dy/dx;
      k2 = k*k;

      p = (arcpek->x_a + k2 * linpek->crd1_l.x_gm - k *
          (linpek->crd1_l.y_gm - arcpek->y_a)) / (1.0 + k2);

      q = (arcpek->x_a * arcpek->x_a + k2 * linpek->crd1_l.x_gm *
          linpek->crd1_l.x_gm + 2.0 * k * linpek->crd1_l.x_gm * 
          (arcpek->y_a - linpek->crd1_l.y_gm) + (linpek->crd1_l.y_gm - 
          arcpek->y_a) * (linpek->crd1_l.y_gm - arcpek->y_a) - 
          arcpek->r_a * arcpek->r_a) / (1.0 + k2);
/*
***Do they intersect ?
*/
      if ( (tt=p*p-q) < 0.0 && tt > -TOL2 ) tt = 0.0;
      if ( tt >= 0.0 )
        {
/*
***Yes, analytical solution.
*/
        x1 = p+SQRT(tt);
        y1 = k*(x1-linpek->crd1_l.x_gm) + linpek->crd1_l.y_gm;
        x2 = p-SQRT(tt);     
        y2 = k*(x2-linpek->crd1_l.x_gm) + linpek->crd1_l.y_gm;
        }
/*
***No intersect.
*/
      else
        {
        *noint = 0;
        return(0);
        }
/*
***Compute line parametric values.
*/
      t1[0] = 1.0 + (x1 - linpek->crd1_l.x_gm) / dx;
      t1[1] = 1.0 + (x2 - linpek->crd1_l.x_gm) / dx;
      }
/*
***Compute arc parametric values.
*/
   dx = x1 - arcpek->x_a;
   dy = y1 - arcpek->y_a;
   GE315(arcpek,dx,dy,&t2[0]);

   dx = x2 - arcpek->x_a;
   dy = y2 - arcpek->y_a;
   GE315(arcpek,dx,dy,&t2[1]);
/*
***If *noint > 0, remove intersects outside actual length of entity.
*/
   if ( *noint > 0 )
     {
     *noint = 2;
     if ( t1[0] < 1.0-TOL4 || t1[0] > 2.0+TOL4 ||
          t2[0] < 1.0-TOL4 || t2[0] > 2.0+TOL4 )
       {
       t1[0] = t1[1];
       t2[0] = t2[1];
       *noint = 1;
       }

     if ( t1[1] < 1.0-TOL4 || t1[1] > 2.0+TOL4 ||
          t2[1] < 1.0-TOL4 || t2[1] > 2.0+TOL4 )
       {
       *noint = *noint - 1;
       }
     }
   else *noint = 2;
/*
***Copy remaining solutions to u1 and u2.
*/
   for ( i=0; i<*noint; ++i )
      {
      if ( pstr1->hed_un.type == LINTYP ) 
         {
         u1[i] = t1[i];
         u2[i] = t2[i];
         }
      else
         {
         u1[i] = t2[i];
         u2[i] = t1[i];
         }
      }
/*
***If more than one solution left sort in increasing order
***with respect of the first entity.
*/
   if ( *noint > 1 && u1[0] > u1[1] )
      {
      tmp = u1[0];
      u1[0] = u1[1];
      u1[1] = tmp;

      tmp = u2[0];
      u2[0] = u2[1];
      u2[1] = tmp;
      }

   return(0);
  }
예제 #7
0
/* Sun rise-set calculation algorithm.
 * Algorithm description:   http://williams.best.vwh.net/sunrise_sunset_algorithm.htm
 *
 *	Almanac for Computers, 1990
 *	published by Nautical Almanac Office
 *	United States Naval Observatory
 *	Washington, DC 20392
 *
 * Parameters:
 *  yd					- day of the year (1..365)
 *  latitude, longitude	- Sample: 32.27, 34.85 for Netania israel
 *  riseset				- ESUNRISE or ESUNSET
 *
 * Returns: UTC hour of the event (a real number).
*/
double sunriseset( int yd, double latitude, double longitude, ERiseSet riseset )
{
	// 96 degrees    - Calculate Civil twilight time. Used as indication if
	//   it is (usually) bright enough for outdoor activities without additional lighting.
	// 90 degrees 5' - Calculate true Sunrise/Sunset time. Used to check if
	//   the Sun itself is visible above the horizont in ideal conditions.
	const double zenith = 96;

	double sinDec, cosDec, cosH;
	double H, T, UT;

	// Rise / Set
	int op = (riseset==ESUNRISE ? 1:-1);

	// Convert the longitude to hour value and calculate an approximate time
	double lngHour = longitude / 15;

	// if rising time is desired:
	double t = yd + ((12 - (6*op) - lngHour) / 24);

	// Calculate the Sun's mean anomaly
	double M = (0.9856 * t) - 3.289;

	// Calculate the Sun's true longitude
	double L = M + (1.916 * SIN(M)) + (0.020 * SIN(2 * M)) + 282.634;

	// Calculate the Sun's right ascension
	double RA = ATAN(0.91764 * TAN(L));

	// Right ascension value needs to be in the same quadrant as L
	double Lquadrant  = (floor( L/90)) * 90;
	double RAquadrant = (floor(RA/90)) * 90;

	RA = RA + (Lquadrant - RAquadrant);

	// Right ascension value needs to be converted into hours
	RA = RA / 15;

	// Calculate the Sun's declination
	sinDec = 0.39782 * SIN(L);
	cosDec = COS(ASIN(sinDec));

	// Calculate the Sun's local hour angle
	cosH = (COS(zenith) - (sinDec * SIN(latitude))) / (cosDec * COS(latitude));
	if( cosH < -1 || cosH > 1 )
		// The sun never rises or sets on this location (on the specified date)
		return -1;

	// Finish calculating H and convert into hours
	H = 180 + (180 - ACOS(cosH))*op;
	H = H / 15;

	// Calculate local mean time of rising/setting
	T = H + RA - (0.06571 * t) - 6.622;

	// Adjust back to UTC
	UT = T - lngHour;

	// UT potentially needs to be adjusted into the range [0,24) by adding/subtracting 24
	if (UT < 0)   UT += 24;
	if (UT >= 24) UT -= 24;

	return UT;
}
예제 #8
0
/*.BE*/
int spltrans                                      /* transformiert-parametr. kub. Polynomspline .......*/
/*.BA*/
/*.IX{spltrans}*/
/*.BE*/
(
int  m,                                           /* Anzahl der Stuetzpunkte ..............*/
REAL x[],                                         /* Stuetzstellen ........................*/
REAL y[],                                         /* Stuetzwerte ..........................*/
int  mv,                                          /* Art der Koordinatenverschiebung ......*/
REAL px[],                                        /* Koordinaten des ......................*/
REAL py[],                                        /* Verschiebepunktes P ..................*/
REAL a[],                                         /* Splinekoeff. von (phi-phin[i])^0 .....*/
REAL b[],                                         /* Splinekoeff. von (phi-phin[i]) .......*/
REAL c[],                                         /* Splinekoeff. von (phi-phin[i])^2 .....*/
REAL d[],                                         /* Splinekoeff. von (phi-phin[i])^3 .....*/
REAL phin[],                                      /* Winkelkoordinaten der Stuetzpunkte ...*/
REAL *phid                                        /* Drehwinkel des Koordinatensystems ....*/
)                                                 /* Fehlercode ...........................*/
/*.BA*/

/***********************************************************************
 * die Koeffizienten einer transformiert-parametrischen interpolieren-  *
 * den kubischen Splinefunktion fuer eine geschlossene, ueberall glatte *
 * Kurve berechnen.                                                     *
.BE*)
* Eine transformiert-parametrische kubische Splinefunktion ist eine    *
* periodische kubische Splinefunktion wie in der Funktion spline(),    *
* jedoch in Polarkoordinatendarstellung. Dies ermoeglicht in vielen    *
* Faellen die Interpolation von Daten, deren Stuetzstellen nicht mono- *
* ton steigend angeordnet sind, ohne echte parametrische Splines (wie  *
* in der Funktion parspl()) berechnen zu muessen.                      *
* Hierzu transformiert die Funktion die eingegebenen Punkte zunaechst  *
* auf Polarkoordinaten (phin[i],a[i]), wobei phin[i] der Winkel und    *
* a[i] die Laenge des Ortsvektors von (x[i],y[i]) ist, i=0(1)m-1. Dies *
* muss so moeglich sein, dass die Winkelwerte phin[i] streng monoton   *
 * steigen, andernfalls ist das transformiert-parametrische Verfahren   *
 * nicht anwendbar. Dann wird eine periodische kubische Splinefunktion  *
 * mit den Winkeln phin[i] als Stuetzstellen berechnet, die die Vektor- *
 * laengen a[i] interpoliert. Um die Monotonie der phin[i] zu errei-    *
 * chen, kann es notwendig sein, den Koordinatenursprung auf einen      *
 * Punkt  P = (px, py)  zu verschieben und das Koordinatensystem um ei- *
 * nen Winkel phid zu drehen. (px, py) muss so in der durch die         *
 * (x[i], y[i])  beschriebenen Flaeche liegen, dass jeder von P ausge-  *
 * hende Polarstrahl die Randkurve der Flaeche nur einmal schneidet.    *
 * P kann sowohl vom Benutzer vorgegeben als auch von der Funktion be-  *
 * rechnet werden. Der hier berechnete Wert ist allerdings nur als Vor- *
 * schlagswert aufzufassen, der in unguenstigen Faellen nicht immer die *
 * Bedingungen erfuellt. Ausserdem muessen die (x[i],y[i]) in der Rei-  *
 * henfolge angeordnet sein, die sich ergibt, wenn man die Randkurve    *
 * der Flaeche, beginnend bei i = 1, im mathematisch positiven Sinn     *
 * durchlaeuft. Da die Kurve geschlossen ist, muss  x[m-1] = x[0]  und  *
 * y[m-1] = y[0]  sein.                                                 *
 *                                                                      *
 * Eingabeparameter:                                                    *
 * =================                                                    *
 * m:    Anzahl der Stuetzstellen (mindestens 3)                        *
 * x:    [0..m-1]-Vektor mit den Stuetzstellen                          *
 * y:    [0..m-1]-Vektor mit den zu interpolierenden Stuetzwerten       *
 * mv:   Marke fuer die Verschiebung des Koordinatenursprungs.          *
 *       mv > 0: Der Benutzer gibt die Koordinaten px, py vor.          *
 *       mv = 0: keine Verschiebung (d.h. px = py = 0)                  *
 *       mv < 0: px und py werden hier berechnet.                       *
 *               Es wird gesetzt:                                       *
 *               px = (xmax + xmin) / 2                                 *
 *               py = (ymax + ymin) / 2                                 *
 *               mit xmax = max(x[i]), xmin = min(x[i]),                *
 *                   ymax = max(y[i]), ymin = min(y[i]), i=0(1)m-1.     *
 *               Zur Beachtung: Hierdurch ist nicht notwendigerweise    *
 *               sichergestellt, dass P die oben genannten Bedingungen  *
 *               erfuellt. Falls die Funktion mit dem Fehlercode -3     *
 *               endet, muss P vom Benutzer vorgegeben werden.          *
 *                                                                      *
 * px: \ fuer mv > 0: vorgegebene Koordinaten des Punktes P             *
 * py: /                                                                *
 *                                                                      *
 * Ausgabeparameter:                                                    *
 * =================                                                    *
 * a: \  [0..m-1]-Vektoren mit Splinekoeffizienten in der Darstellung   *
 * b:  \     S(phi)  =  a[i] + b[i] * (phi - phin[i])                   *
 * c:  /                     + c[i] * (phi - phin[i]) ^ 2               *
 * d: /                      + d[i] * (phi - phin[i]) ^ 3               *
 *       fuer  phin[i] <= phi <= phin[i+1],   i=0(1)m-2 .               *
 *       Die a[i] sind die Vektorlaengen der (x[i],y[i]) in der Polar-  *
 *       koordinatendarstellung. b, c und d werden auch noch fuer       *
 *       Zwischenergebnisse missbraucht.                                *
 * phin: [0..m-1]-Vektor mit den Winkelkoordinaten der (x[i],y[i]) in   *
 *       der Polarkoordinatendarstellung.                               *
 *       Es ist phin[0]   = 0,                                          *
 *              phin[i]   = arctan((y[i] - py) / (x[i] - px)) - phid,   *
 *                          i=1(1)m-2                                   *
 *              phin[m-1] = 2 * Pi                                      *
 *                                                                      *
 * px: \ Koordinaten des Verschiebungspunktes P                         *
 * py: /                                                                *
 * phid: Winkel, um den das Koordinatensystem eventuell gedreht wurde.  *
 *       Es ist phid = arctan(y[0] / x[0]).                             *
 *                                                                      *
 * Funktionswert:                                                       *
 * ==============                                                       *
 *  0: kein Fehler                                                      *
 * -1: m < 3                                                            *
 * -3: Die phin[i] sind nicht streng monoton steigend.                  *
 * -4: x[m-1] != x[0]  oder  y[m-1] != y[0]                             *
 * >0: Fehler in spline()                                               *
 *                                                                      *
 * benutzte globale Namen:                                              *
 * =======================                                              *
 * spline, REAL, PI, sqr, SQRT, ACOS, ZERO, TWO                         *
.BA*)
***********************************************************************/
/*.BE*/

{
   REAL xmin,                                     /* Minimum der x[i]                      */
      xmax,                                       /* Maximum der x[i]                      */
      ymin,                                       /* Minimum der y[i]                      */
      ymax,                                       /* Maximum der y[i]                      */
      sa,                                         /* sin(-phid)                            */
      ca;                                         /* cos(-phid)                            */
   int  n,                                        /* m - 1, Index der letzten Stuetzstelle */
      i;                                          /* Laufvariable                          */

   n = m - 1;

   /* ---------------- die Vorbedingungen ueberpruefen --------------- */
   if (n < 2)
      return -1;
   if (x[0] != x[n] || y[0] != y[n])
      return -4;

   /* ---------------- die Koordinaten transformieren ---------------- */
   if (mv == 0)                                   /* das Koordinatensystem  nicht verschieben? */
   {
      *px = *py = ZERO;
      for (i = 0; i <= n; i++)
         b[i] = x[i],
            c[i] = y[i];
   }
   else                                           /* den Koordinatenursprung nach (px, py) verschieben? */
   {
      if (mv < 0)                                 /* Sollen py und py berechnet werden? */
      {
         xmax = x[0];
         xmin = x[0];
         ymax = y[0];
         ymin = y[0];
         for (i = 1; i <= n; i++)
         {
            if (x[i] > xmax)
               xmax = x[i];
            if (x[i] < xmin)
               xmin = x[i];
            if (y[i] > ymax)
               ymax = y[i];
            if (y[i] < ymin)
               ymin = y[i];
         }
         *px = (xmax + xmin) / TWO;
         *py = (ymax + ymin) / TWO;
      }

      for (i = 0; i <= n; i++)                    /* die verschoben Punkte (x[i],y[i]) */
         b[i] = x[i] - *px,                       /* in (b[i],c[i]) aufgewahren        */
            c[i] = y[i] - *py;
   }

   /* ---- die transformierten Stuetzstellen berechnen:           ---- */
   /* ---- 1. die a[i] berechnen. Abbruch, wenn  a[i] = 0, d. h.  ---- */
   /* ----    wenn (px, py) mit einer Stuetzstelle zusammenfaellt ---- */
   for (i = 0; i <= n; i++)
   {
      a[i] = SQRT(sqr(b[i]) + sqr(c[i]));
      if (a[i] == ZERO)
         return -3;
   }

   /*------------------------------------------------------------------*/
   /* 2. die um alpha gedrehten Koordinaten X1, Y1 berechnen           */
   /*    nach den Gleichungen:                                         */
   /*                                                                  */
   /*  (X1)   ( cos(alpha)   -sin(alpha) ) (X)                         */
   /*  (  ) = (                          ) ( )                         */
   /*  (Y1)   ( sin(alpha)    cos(alpha) ) (Y)                         */
   /*                                                                  */
   /*  mit alpha = -phid                                               */
   /*------------------------------------------------------------------*/

   *phid = ACOS(b[0] / a[0]);
   if (c[0] < ZERO)
      *phid = TWO * PI - *phid;
   ca = b[0] / a[0];
   sa = -c[0] / a[0];
   for (i = 0; i <= n; i++)                       /* die gedrehten Koordinaten */
      d[i] = b[i] * ca - c[i] * sa,               /* (b[i],c[i]) in            */
         c[i] = b[i] * sa + c[i] * ca;            /* (d[i],c[i] ablegen        */

   /* ------ die Winkelkoordinaten phin[i] berechnen. Abbruch,  ------ */
   /* ------ wenn die Winkel nicht streng monoton steigend sind ------ */
   phin[0] = ZERO;
   for (i = 1; i < n; i++)
   {
      phin[i] = ACOS(d[i] / a[i]);
      if (c[i] < ZERO)
         phin[i] = TWO * PI - phin[i];
      if (phin[i] <= phin[i - 1])
         return -3;
   }
   phin[n] = TWO * PI;

   /* --------------- die Splinekoeffizienten berechnen -------------- */
   return spline(n + 1, phin, a, 4, ZERO, ZERO, 0, b, c, d);
}
예제 #9
0
		REAL Vec2::angle(const Vec2& other) const
		{
			return ACOS(((*this)*other)/(length()*other.length()));
		}
예제 #10
0
		REAL	Vec2::angle() const
		{
			Vec2 n=this->normal();
			REAL angle=ACOS(n.x);
			return SETSIGN(angle,SIGNBIT(n.y));
		}
예제 #11
0
void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float targetY, int bendDir, float alpha) {
	float px = parent->x, py = parent->y, psx = parent->scaleX, psy = parent->scaleY;
	float cx = child->x, cy, csx = child->scaleX, cwx, cwy;
	int o1, o2, s2, u;
	spBone* pp = parent->parent;
	float tx, ty, dx, dy, l1, l2, a1, a2, r;
	float id, x, y;
	if (alpha == 0) {
		spBone_updateWorldTransform(child);
		return;
	}
	if (psx < 0) {
		psx = -psx;
		o1 = 180;
		s2 = -1;
	} else {
		o1 = 0;
		s2 = 1;
	}
	if (psy < 0) {
		psy = -psy;
		s2 = -s2;
	}
	if (csx < 0) {
		csx = -csx;
		o2 = 180;
	} else
		o2 = 0;
	r = psx - psy;
	u = (r < 0 ? -r : r) <= 0.0001f;
	if (!u) {
		cy = 0;
		cwx = parent->a * cx + parent->worldX;
		cwy = parent->c * cx + parent->worldY;
	} else {
		cy = child->y;
		cwx = parent->a * cx + parent->b * cy + parent->worldX;
		cwy = parent->c * cx + parent->d * cy + parent->worldY;
	}
	id = 1 / (pp->a * pp->d - pp->b * pp->c);
	x = targetX - pp->worldX;
	y = targetY - pp->worldY;
	tx = (x * pp->d - y * pp->b) * id - px;
	ty = (y * pp->a - x * pp->c) * id - py;
	x = cwx - pp->worldX;
	y = cwy - pp->worldY;
	dx = (x * pp->d - y * pp->b) * id - px;
	dy = (y * pp->a - x * pp->c) * id - py;
	l1 = SQRT(dx * dx + dy * dy);
	l2 = child->data->length * csx;
	if (u) {
		float cosine, a, b;
		l2 *= psx;
		cosine = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2);
		if (cosine < -1) cosine = -1;
		else if (cosine > 1) cosine = 1;
		a2 = ACOS(cosine) * bendDir;
		a = l1 + l2 * cosine;
		b = l2 * SIN(a2);
		a1 = ATAN2(ty * a - tx * b, tx * a + ty * b);
	} else {
		float a = psx * l2, b = psy * l2;
		float aa = a * a, bb = b * b, ll = l1 * l1, dd = tx * tx + ty * ty, ta = ATAN2(ty, tx);
		float c0 = bb * ll + aa * dd - aa * bb, c1 = -2 * bb * l1, c2 = bb - aa;
		float d = c1 * c1 - 4 * c2 * c0;
		float minAngle = 0, minDist = FLT_MAX, minX = 0, minY = 0;
		float maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0;
		float x = l1 + a, dist = x * x, angle, y;
		if (d >= 0) {
			float q = SQRT(d), r0, r1;
			if (c1 < 0) q = -q;
			q = -(c1 + q) / 2;
			r0 = q / c2; r1 = c0 / q;
			r = ABS(r0) < ABS(r1) ? r0 : r1;
			if (r * r <= dd) {
				y = SQRT(dd - r * r) * bendDir;
				a1 = ta - ATAN2(y, r);
				a2 = ATAN2(y / psy, (r - l1) / psx);
				goto outer;
			}
		}
		if (dist > maxDist) {
			maxAngle = 0;
			maxDist = dist;
			maxX = x;
		}
		x = l1 - a;
		dist = x * x;
		if (dist < minDist) {
			minAngle = PI;
			minDist = dist;
			minX = x;
		}
		angle = ACOS(-a * l1 / (aa - bb));
		x = a * COS(angle) + l1;
		y = b * SIN(angle);
		dist = x * x + y * y;
		if (dist < minDist) {
			minAngle = angle;
			minDist = dist;
			minX = x;
			minY = y;
		}
		if (dist > maxDist) {
			maxAngle = angle;
			maxDist = dist;
			maxX = x;
			maxY = y;
		}
		if (dd <= (minDist + maxDist) / 2) {
			a1 = ta - ATAN2(minY * bendDir, minX);
			a2 = minAngle * bendDir;
		} else {
			a1 = ta - ATAN2(maxY * bendDir, maxX);
			a2 = maxAngle * bendDir;
		}
	}
	outer: {
		float os = ATAN2(cy, cx) * s2;
		a1 = (a1 - os) * RAD_DEG + o1 - parent->rotation;
		if (a1 > 180) a1 -= 360;
		else if (a1 < -180) a1 += 360;
		spBone_updateWorldTransformWith(parent, px, py, parent->rotation + a1 * alpha, parent->scaleX, parent->scaleY, 0, 0);
		a2 = ((a2 + os) * RAD_DEG - child->shearX) * s2 + o2 - child->rotation;
		if (a2 > 180) a2 -= 360;
		else if (a2 < -180) a2 += 360;
		spBone_updateWorldTransformWith(child, cx, cy, child->rotation + a2 * alpha, child->scaleX, child->scaleY, child->shearX, child->shearY);
	}
}
예제 #12
0
// calc angle between 0 to pi
m_real	vectorn::angle(vectorn const& b) const 
{
	vectorn const& a=*this;
	return (m_real)(ACOS(a.cosTheta(b)));
}