Пример #1
0
float VectorDistance (vec3_t v1, vec3_t v2)
{
	vec3_t diff;

	VectorSubtract(v1, v2, diff);

	return vlen(diff);
}
Пример #2
0
/*  Variance of data by corrected two-pass algorithm  */
double variance (const VEC v){
	assert(NULL!=v);
	const unsigned int len = vlen(v);
	const double vmean = mean(v);
	const double correction = suma_vec(v,-vmean);

	return (sample_variance_naive(v)-correction*correction/len)/(len-1);
}
Пример #3
0
double quantile (const VEC v, const double q){
	assert(NULL!=v);
	assert(q>=0. && q<=1.);
	VEC vcopy = copy_vec(v);
	qsort (vcopy->x,vlen(vcopy),sizeof(double),CmpDouble);
	const double med = quantile_fromsorted(vcopy,q);
	free_vec(vcopy);
	return med;
}
Пример #4
0
void Wall::revalidate ()
{
    j = next->v1-v1;
    len = vlen(j);
    j /= len;

    // Cache the inverse slope of the wall. Used in Area::pointin.
    tslope = ((next->v1.x - v1.x) / (next->v1.y - v1.y));
}
Пример #5
0
void Helpers::normalize(qreal *a)
{
  double b;

  b = vlen(a);
  a[0] /= b;
  a[1] /= b;
  a[2] /= b;
}
Пример #6
0
// Called from client.c
void GrappleService()
{
    vec3_t hookVector, hookVelocity;
    gedict_t *enemy;

    // drop the hook if player lets go of fire
    if ( !self->s.v.button0 )
    {
        if ( self->s.v.weapon == IT_HOOK )
        {
            GrappleReset( self->hook );
            return;
        }
    }

    enemy = PROG_TO_EDICT( self->hook->s.v.enemy );

    // If hooked to a player, track them directly!
    if ( enemy->ct == ctPlayer )
    {
        VectorSubtract( enemy->s.v.origin, self->s.v.origin, hookVector );
    }
    else
        VectorSubtract( self->hook->s.v.origin, self->s.v.origin, hookVector );

    // No longer going to factor maxspeed into grapple velocity
    // Using standard grapple velocity of 800 set from original 3wave
    // purectf velocity = 2.35 * 320 or 360 * 1 = 750 or 846

    VectorCopy( hookVector, hookVelocity );
    VectorNormalize( hookVelocity );

    if ( self->ctf_flag & CTF_RUNE_HST )
        VectorScale( hookVelocity, 1000, self->s.v.velocity );
    else
        VectorScale( hookVelocity, 800, self->s.v.velocity );

    if ( vlen(hookVector) <= 100 ) // cancel chain sound
    {
        FreezeGravity( self );
        if ( self->ctf_sound )
        {
            // If there is a chain, ditch it now. We're
            // close enough. Having extra entities lying around
            // is never a good idea.
            if ( self->hook->s.v.goalentity )
            {
                PROG_TO_EDICT(self->hook->s.v.goalentity)->s.v.think     = (func_t) RemoveChain;
                PROG_TO_EDICT(self->hook->s.v.goalentity)->s.v.nextthink = g_globalvars.time;
            }

            sound( self, CHAN_NO_PHS_ADD + CHAN_WEAPON, "weapons/chain3.wav", 1, ATTN_NORM );
            self->ctf_sound = false; // reset the sound channel.
        }
    }
}
Пример #7
0
/* Ensure that the array contains enough memory for @len
 * bits, expanding the bitvector if necessary */
static void bv_ensure(bitvector_t *bv, unsigned int len)
{
    len = vlen(len);        /* now number of bytes */
    if (len > bv->alloc) {
        unsigned int newalloc = ((len + QUANTUM-1) / QUANTUM) * QUANTUM;
        bv->bits = (unsigned char *)xrealloc(bv->bits, newalloc);
        memset(bv->bits + bv->alloc, 0, newalloc - bv->alloc);
        bv->alloc = newalloc;
    }
}
Пример #8
0
double sample_variance_naive ( const VEC v){
	assert(NULL!=v);
	const unsigned int len = vlen(v);
	const double vmean = mean(v);
	double sumsqr = 0.;
	for ( unsigned int i=0 ; i<len ; i++){
		sumsqr += (vget(v,i)-vmean)*(vget(v,i)-vmean);
	}
	return sumsqr;
}
	//Surface
	double area() {
		double res = 0;
		if (n == 3) {
			Point p = cross(P[0], P[1], P[2]);
			res = vlen(p) / 2.0;
			return res;
		}
		for (int i = 0; i < num; i++)
		res += area(P[F[i].a], P[F[i].b], P[F[i].c]);
		return res / 2.0;
	}
Пример #10
0
EXPORTED void bv_oreq(bitvector_t *a, const bitvector_t *b)
{
    unsigned int n;
    unsigned int i;

    bv_ensure(a, b->length);
    n = vlen(b->length+1);
    for (i = 0 ; i <= n ; i++)
        a->bits[i] |= b->bits[i];
    a->length = MAX(a->length, b->length);
}
Пример #11
0
t_vector		get_cone_normale(t_vector p, t_icone *cone)
{
	double		m;
	t_vector	res;

	m = pow(vlen(vsub(p, cone->vertex)), 2) / vscalar_multiple(vsub(p,
			cone->vertex), cone->vector);
	res = vsum(cone->vertex, vk_multiple(cone->vector, m));
	res = vnormalize(vsub(p, res));
	return (res);
}
Пример #12
0
Файл: player.c Проект: deurk/ktx
void player_chain3()
{
	self->s.v.frame = 139;
	self->think = ( func_t ) player_chain4;
	self->s.v.nextthink = g_globalvars.time + 0.1;
	self->s.v.weaponframe = 3;
	if ( !self->hook_out )
		player_chain5();
	else if ( vlen(self->s.v.velocity) >= 750 )
		player_chain4();
}
Пример #13
0
void CheckSentry( gedict_t * gunhead )
{
    vec3_t dist;
    gedict_t *gunbase;

    gunbase = gunhead->trigger_field;
    VectorSubtract( gunbase->s.v.origin, gunhead->s.v.origin, dist );
    if ( vlen( dist ) > 15 )
    {
	G_bprint( 1, "%s's sentry gun malfunctioned\n", self->real_owner->s.v.netname );
	Sentry_Die(  );
    }
}
Пример #14
0
/*  Some unnecessary vector copies when this function is combined with median */
double mad ( const VEC v){
	assert(NULL!=v);
	const double vmedian = median(v);
	VEC vcopy = copy_vec (v);
	const unsigned int len = vlen(vcopy);
	for ( unsigned int i=0 ; i<len ; i++){
		vset(vcopy,i,fabs(vget(vcopy,i)-vmedian));
	}
	const double devmedian = median(vcopy);
	free_vec(vcopy);

	return devmedian * MADSCALE;
}
Пример #15
0
void Motion(int x, int y)
{
    bool changed = false;
    const int dx = x - _mouseX;
    const int dy = y - _mouseY;
    int viewport[4];
    glGetIntegerv(GL_VIEWPORT, viewport);
    if (dx == 0 && dy == 0)
	return;
    if (_mouseMiddle || (_mouseLeft && _mouseRight)) {
	double s = exp((double) dy * 0.01);
	glScalef(s, s, s);
	changed = true;
    }

    else if (_mouseLeft) {
	double ax, ay, az;
	double bx, by, bz;
	double angle;
	ax = dy;
	ay = dx;
	az = 0.0;
	angle = vlen(ax, ay, az) / (double) (viewport[2] + 1) * 180.0;

	/* Use inverse matrix to determine local axis of rotation */
	bx = _matrixI[0] * ax + _matrixI[4] * ay + _matrixI[8] * az;
	by = _matrixI[1] * ax + _matrixI[5] * ay + _matrixI[9] * az;
	bz = _matrixI[2] * ax + _matrixI[6] * ay + _matrixI[10] * az;
	glRotatef(angle, bx, by, bz);
	changed = true;
    }

    else if (_mouseRight) {
	double px, py, pz;
	pos(&px, &py, &pz, x, y, viewport);
	glLoadIdentity();
	glTranslatef(px - _dragPosX, py - _dragPosY, pz - _dragPosZ);
	glMultMatrixd(_matrix);
	_dragPosX = px;
	_dragPosY = py;
	_dragPosZ = pz;
	changed = true;
    }
    _mouseX = x;
    _mouseY = y;
    if (changed) {
	getMatrix();
	glutPostRedisplay();
    }
}
Пример #16
0
void traceJigData(struct part *part, struct xyz *positions) {
    double x;
    int i;
    struct jig *j;

    __p = __line;
    __p += sprintf(__p, "%10.4f ", Iteration * Dt / PICOSEC);
    
    for (i=0; i<part->num_jigs; i++) {
        j = part->jigs[i];
        switch (j->type) {
        case DihedralMeter:
        case AngleMeter:
	    __p += sprintf(__p, " %15.5f", j->data);
	    break;
        case Ground:
	    x=vlen(j->xdata)/1e4;
	    __p += sprintf(__p, " %15.2f", x / j->data);
	    j->data=0.0;
	    vsetc(j->xdata, 0.0);
	    break;
        case RadiusMeter:
        case LinearMotor:
	    // convert from picometers to angstroms
	    __p += sprintf(__p, " %15.4f", 0.01 * j->data);
	    j->data = 0.0;
	    break;
        case Thermometer:
        case Thermostat:
	    __p += sprintf(__p, " %15.2f", j->data);
	    j->data = 0.0;
	    break;
        case RotaryMotor:
	    __p += sprintf(__p, " %15.3f %15.3f", j->data, j->data2);
	    j->data = 0.0;
	    j->data2 = 0.0;
	    break;
	}
    }
    if (PrintPotentialEnergy) {
        double potential_energy = calculatePotential(part, positions);
        double kinetic_energy = calculateKinetic(part);
        
	__p += sprintf(__p, " %15.6f", potential_energy);
	__p += sprintf(__p, " %15.6f", kinetic_energy);
	__p += sprintf(__p, " %15.6f", potential_energy + kinetic_energy);
    }
    sprintf(__p, "\n"); // each snapshot is one line
    write_traceline(__line);
}
Пример #17
0
Файл: player.c Проект: deurk/ktx
void player_chain4()
{
	// Original ctf grapple used frame 73 here, but that causes problems with cl_deadbodyfilter 2
	// Frame 139 is a decent alternative especially given that 73 never looked good anyway
	// self->s.v.frame = 73;
	self->s.v.frame = 139;
	self->think = ( func_t ) player_chain5;
	self->s.v.nextthink = g_globalvars.time + 0.1;
	self->s.v.weaponframe = 4;
	if ( !self->hook_out )
		player_chain5();
	else if ( vlen(self->s.v.velocity) < 750 )  
		player_chain3(); 
}
Пример #18
0
 double GetArea()     //凸包表面积
 {
     double res = 0.0;
     if (n == 3)
     {
         Point p = cross(P[0], P[1], P[2]);
         res = vlen(p) / 2.0;
         return res;
     }
     for (int i = 0; i < num; i++)
     {
         res += area(P[F[i].a], P[F[i].b], P[F[i].c]);
     }
     return res / 2.0;
 }
Пример #19
0
// Is player visible?
static qboolean Cam_IsVisible(player_state_t *player, vec3_t vec)
{
	pmtrace_t trace;
	vec3_t v;
	float d;

	trace = Cam_DoTrace(player->origin, vec);
	if (trace.fraction != 1 || /*trace.inopen ||*/ trace.inwater)
		return false;
	// check distance, don't let the player get too far away or too close
	VectorSubtract(player->origin, vec, v);
	d = vlen(v);
	if (d < 16)
		return false;
	return true;
}
Пример #20
0
/*
=============
ai_melee

=============
*/
void ai_melee()
{
	vec3_t	delta;
	float	ldmg;

	if ( !self->s.v.enemy )
		return;		// removed before stroke

	VectorSubtract( PROG_TO_EDICT( self->s.v.enemy )->s.v.origin, self->s.v.origin, delta );

	if ( vlen( delta ) > 60 )
		return;

	ldmg = ( g_random() + g_random() + g_random() ) * 3;
	PROG_TO_EDICT( self->s.v.enemy )->deathtype = dtSQUISH; // FIXME
	T_Damage( PROG_TO_EDICT( self->s.v.enemy ), self, self, ldmg );
}
Пример #21
0
Файл: player.c Проект: deurk/ktx
void VelocityForDamage( float dm, vec3_t v )
{
	vec3_t          v2;

	if ( vlen( damage_inflictor->s.v.velocity ) > 0 )
	{
		VectorScale( damage_inflictor->s.v.velocity, 0.5, v );
		VectorSubtract( self->s.v.origin, damage_inflictor->s.v.origin, v2 );
		VectorNormalize( v2 );
		VectorScale( v2, 25, v2 );
		VectorAdd( v, v2, v );
//  v = 0.5 * damage_inflictor->s.v.velocity;
//  v = v + (25 * normalize((self->s.v.origin)-damage_inflictor->s.v.origin));
		v[2] = 100 + 240 * g_random();
		v[0] = v[0] + ( 200 * crandom() );
		v[1] = v[1] + ( 200 * crandom() );
		//dprint ("Velocity gib\n");                
	} else
	{
		v[0] = 100 * crandom();
		v[1] = 100 * crandom();
		v[2] = 200 + 100 * g_random();
	}

	//v[0] = 100 * crandom();
	//v[1] = 100 * crandom();
	//v[2] = 200 + 100 * g_random();

	if ( dm > -50 )
	{
		//      dprint ("level 1\n");
		VectorScale( v, 0.7, v );
//  v = v * 0.7;
	} else if ( dm > -200 )
	{
		//      dprint ("level 3\n");
		VectorScale( v, 2, v );
//  v = v * 2;
	} else
		VectorScale( v, 10, v );
//  v = v * 10;

	return;			//v;
}
Пример #22
0
void sgAimNew( gedict_t* self, gedict_t* targ, vec3_t src, vec3_t dst, vec3_t norm_dir)
{
    vec3_t  dir,  tmp;
    trap_makevectors( self->s.v.v_angle );

    VectorAdd( self->s.v.origin, self->s.v.view_ofs, src );
    VectorAdd( targ->s.v.origin, targ->s.v.view_ofs, dst );
    VectorSubtract( dst, src, dir );

    normalize(dir, norm_dir);

    //чтобы не попадать в подставку
    traceline( PASSVEC3( src ), PASSVEC3( dst ), 0, self );

    if( (PROG_TO_EDICT(g_globalvars.trace_ent) == self->trigger_field) && vlen(dir) > 100 )
    {
        VectorScale( norm_dir, 60, tmp);
        VectorAdd(src,tmp,src);
    }
}
Пример #23
0
bool ray_triangle(
    vec3 p , vec3 d, vec3 A,vec3 B, vec3 C
){
    //not matrix translate rotate?
    vec3 N=vcross(B-A, C-A);

    dassert(vlen(N)!=0.f && "RAY_TRIANGLE");

//	bool backface = vdot( N, d ) > 0.f;

	float t=vdot(A-p,N)/vdot(N,d);
	
    //too far away or zero
    if(t>=1.||t<=0.f)
        return 0;
	
/*	
	float va = vdot( N , vcross( B-p, C-p ) );
	float vb = vdot( N , vcross( C-p, A-p ) );
	float vc = vdot( N , vcross( A-p, B-p ) );
	float u = va / ( va + vb + vc );
	float v = vb / ( va + vb + vc );
	float w = 1.f - u - v;
	if( u<0.f || v < 0.f || w < 0.f )
		return 0;
*/

	//try uv approach

    // check if ray is inside triangle
	float EPS = -.00001f;//000000001f;
    if( //!backface &&
         (vdot(vcross(A-p,B-p),d)>EPS||
		 vdot(vcross(B-p,C-p),d)>EPS||
	 	 vdot(vcross(C-p,A-p),d)>EPS))
         return 0;//miss triangle

    return 1;
}
Пример #24
0
//unused
static void bondump(FILE *f) {		/* gather bond statistics */
    int histo[50][23], totno[50], btyp, i, j, k, n;
    double r, perc, means[50];
    struct bondStretch *bt;
	
    for (i=0; i<50; i++) {
	totno[i] = 0;
	means[i] = 0.0;
	for (j=0; j<23; j++)
	    histo[i][j]=0;
    }
	
    for (i=0; i<Nexbon; i++) {
	bt=bond[i].type;
	// XXX btyp = bt-bstab;
	totno[btyp]++;
	r=vlen(vdif(Positions[bond[i].an1], Positions[bond[i].an2]));
	means[btyp] += r;
	perc = (r/bt->r0)*20.0 - 8.5;
	k=(int)perc;
	if (k<0) k=0;
	if (k>22) k=22;
	histo[btyp][k]++;
    }
	
    for (i=0; i<BSTABSIZE; i++) if (totno[i]) {
	fprintf(f, "Bond type %s-%s, %d occurences, mean %.2f pm:\n",
		  periodicTable[bstab[i].a1].symbol, periodicTable[bstab[i].a2].symbol, totno[i],
		  means[i]/(double)totno[i]);
	for (j=0; j<23; j++) {
	    if ((j-1)%10) fprintf(f, " |");
	    else fprintf(f, "-+");
	    n=(80*histo[i][j])/totno[i];
	    if (histo[i][j] && n==0) fprintf(f, ".");
	    for (k=0; k<n; k++) fprintf(f, "M");
	    fprintf(f, "\n");
	}}
    fprintf(f, "Iteration %d\n",Iteration);
}
Пример #25
0
/*
=============
range

returns the range catagorization of an entity reletive to self
0	melee range, will become hostile even if back is turned
1	visibility and infront, or visibility and show hostile
2	infront and show hostile
3	only triggered by damage
=============
*/
float range( gedict_t *targ )
{
	vec3_t	spot1, spot2, org;
	float	r;

	VectorAdd( self->s.v.origin, self->s.v.view_ofs, spot1 );
	VectorAdd( targ->s.v.origin, targ->s.v.view_ofs, spot2 );
	VectorSubtract( spot1, spot2, org );

	r = vlen( org );
	if ( r < 120 )
		return RANGE_MELEE;
	if ( r < 500 )
		return RANGE_NEAR;
	if ( r < 1000 )
		return RANGE_MID;

	// so monsters notice player father/faster in bloodfest mode.
	if ( k_bloodfest )
		return RANGE_MID;

	return RANGE_FAR;
}
Пример #26
0
void SUB_CalcMove( vec3_t tdest, float tspeed, void ( *func ) () )
{
	vec3_t          vdestdelta;
	float           len, traveltime;

	if ( !tspeed )
		G_Error( "No speed is defined!" );

	self->think1 = func;
	VectorCopy( tdest, self->finaldest );
	self->s.v.think = ( func_t ) SUB_CalcMoveDone;

	if ( VectorCompare( tdest, self->s.v.origin ) )
	{
		SetVector( self->s.v.velocity, 0, 0, 0 );
		self->s.v.nextthink = self->s.v.ltime + 0.1;
		return;
	}
// set destdelta to the vector needed to move
	VectorSubtract( tdest, self->s.v.origin, vdestdelta )
// calculate length of vector
	    len = vlen( vdestdelta );

// divide by speed to get time to reach dest
	traveltime = len / tspeed;

	if ( traveltime < 0.03 )
		traveltime = 0.03;

// set nextthink to trigger a think when dest is reached
	self->s.v.nextthink = self->s.v.ltime + traveltime;

// scale the destdelta vector by the time spent traveling to get velocity
	VectorScale( vdestdelta, ( 1 / traveltime ), self->s.v.velocity );
	//self.velocity = vdestdelta * (1/traveltime); // qcc won't take vec/float 
}
Пример #27
0
/*! \internal

    \a a, \a b and \a c are corner points of an equilateral triangle.
    (\a x,\a y) is an arbitrary point inside or outside this triangle.

    If (x,y) is inside the triangle, this function returns the double
    point (x,y).

    Otherwise, the intersection of the perpendicular projection of
    (x,y) onto the closest triangle edge is returned, unless this
    intersection is outside the triangle's bounds, in which case the
    corner closest to the intersection is returned instead.

    Yes, it's trigonometry.
*/
QPointF QtColorTriangle::movePointToTriangle(double x, double y, const Vertex &a,
					       const Vertex &b, const Vertex &c) const
{
    // Let v1A be the vector from (x,y) to a.
    // Let v2A be the vector from a to b.
    // Find the angle alphaA between v1A and v2A.
    double v1xA = x - a.point.x();
    double v1yA = y - a.point.y();
    double v2xA = b.point.x() - a.point.x();
    double v2yA = b.point.y() - a.point.y();
    double vpA = vprod(v1xA, v1yA, v2xA, v2yA);
    double cosA = vpA / (vlen(v1xA, v1yA) * vlen(v2xA, v2yA));
    double alphaA = acos(cosA);

    // Let v1B be the vector from x to b.
    // Let v2B be the vector from b to c.
    double v1xB = x - b.point.x();
    double v1yB = y - b.point.y();
    double v2xB = c.point.x() - b.point.x();
    double v2yB = c.point.y() - b.point.y();
    double vpB = vprod(v1xB, v1yB, v2xB, v2yB);
    double cosB = vpB / (vlen(v1xB, v1yB) * vlen(v2xB, v2yB));
    double alphaB = acos(cosB);

    // Let v1C be the vector from x to c.
    // Let v2C be the vector from c back to a.
    double v1xC = x - c.point.x();
    double v1yC = y - c.point.y();
    double v2xC = a.point.x() - c.point.x();
    double v2yC = a.point.y() - c.point.y();
    double vpC = vprod(v1xC, v1yC, v2xC, v2yC);
    double cosC = vpC / (vlen(v1xC, v1yC) * vlen(v2xC, v2yC));
    double alphaC = acos(cosC);

    // Find the radian angles between the (1,0) vector and the points
    // A, B, C and (x,y). Use this information to determine which of
    // the edges we should project (x,y) onto.
    double angleA = angleAt(a.point, contentsRect());
    double angleB = angleAt(b.point, contentsRect());
    double angleC = angleAt(c.point, contentsRect());
    double angleP = angleAt(QPointF(x, y), contentsRect());

    // If (x,y) is in the a-b area, project onto the a-b vector.
    if (angleBetweenAngles(angleP, angleA, angleB)) {
	// Find the distance from (x,y) to a. Then use the slope of
	// the a-b vector with this distance and the angle between a-b
	// and a-(x,y) to determine the point of intersection of the
	// perpendicular projection from (x,y) onto a-b.
	double pdist = sqrt(qsqr(x - a.point.x()) + qsqr(y - a.point.y()));

        // the length of all edges is always > 0
	double p0x = a.point.x() + ((b.point.x() - a.point.x()) / vlen(v2xB, v2yB)) * cos(alphaA) * pdist;
	double p0y = a.point.y() + ((b.point.y() - a.point.y()) / vlen(v2xB, v2yB)) * cos(alphaA) * pdist;

	// If (x,y) is above the a-b line, which basically means it's
	// outside the triangle, then return its projection onto a-b.
	if (pointAbovePoint(x, y, p0x, p0y, a.point.x(), a.point.y(), b.point.x(), b.point.y())) {
	    // If the projection is "outside" a, return a. If it is
	    // outside b, return b. Otherwise return the projection.
	    int n = pointInLine(p0x, p0y, a.point.x(), a.point.y(), b.point.x(), b.point.y());
	    if (n < 0)
		return a.point;
	    else if (n > 0)
		return b.point;

	    return QPointF(p0x, p0y);
	}
    } else if (angleBetweenAngles(angleP, angleB, angleC)) {
	// If (x,y) is in the b-c area, project onto the b-c vector.
	double pdist = sqrt(qsqr(x - b.point.x()) + qsqr(y - b.point.y()));

        // the length of all edges is always > 0
        double p0x = b.point.x() + ((c.point.x() - b.point.x()) / vlen(v2xC, v2yC)) * cos(alphaB) * pdist;
	double p0y = b.point.y() + ((c.point.y() - b.point.y()) / vlen(v2xC, v2yC)) * cos(alphaB) * pdist;

	if (pointAbovePoint(x, y, p0x, p0y, b.point.x(), b.point.y(), c.point.x(), c.point.y())) {
	    int n = pointInLine(p0x, p0y, b.point.x(), b.point.y(), c.point.x(), c.point.y());
	    if (n < 0)
		return b.point;
	    else if (n > 0)
		return c.point;
	    return QPointF(p0x, p0y);
	}
    } else if (angleBetweenAngles(angleP, angleC, angleA)) {
	// If (x,y) is in the c-a area, project onto the c-a vector.
	double pdist = sqrt(qsqr(x - c.point.x()) + qsqr(y - c.point.y()));

        // the length of all edges is always > 0
        double p0x = c.point.x() + ((a.point.x() - c.point.x()) / vlen(v2xA, v2yA)) * cos(alphaC) * pdist;
	double p0y = c.point.y() + ((a.point.y() - c.point.y()) / vlen(v2xA, v2yA)) * cos(alphaC) * pdist;

	if (pointAbovePoint(x, y, p0x, p0y, c.point.x(), c.point.y(), a.point.x(), a.point.y())) {
	    int n = pointInLine(p0x, p0y, c.point.x(), c.point.y(), a.point.x(), a.point.y());
	    if (n < 0)
		return c.point;
	    else if (n > 0)
		return a.point;
	    return QPointF(p0x, p0y);
	}
    }

    // (x,y) is inside the triangle (inside a-b, b-c and a-c).
    return QPointF(x, y);
}
Пример #28
0
// ZOID
//
// Take over the user controls and track a player.
// We find a nice position to watch the player and move there
void Cam_Track(usercmd_t *cmd)
{
	player_state_t *player, *self;
	frame_t *frame;
	vec3_t vec;
	float len;

	if (!cl.spectator)
		return;
	
	if (cl_hightrack.value && !locked)
		Cam_CheckHighTarget();

	if (!autocam || cls.state != ca_active)
		return;

	if (locked && (!cl.players[spec_track].name[0] || cl.players[spec_track].spectator)) {
		locked = false;
		if (cl_hightrack.value)
			Cam_CheckHighTarget();
		else
			Cam_Unlock();
		return;
	}

	frame = &cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK];
	player = frame->playerstate + spec_track;
	self = frame->playerstate + cl.playernum;

	if (!locked || !Cam_IsVisible(player, desired_position)) {
		if (!locked || realtime - cam_lastviewtime > 0.1) {
			if (!InitFlyby(self, player, true))
				InitFlyby(self, player, false);
			cam_lastviewtime = realtime;
		}
	} else
		cam_lastviewtime = realtime;
	
	// couldn't track for some reason
	if (!locked || !autocam)
		return;

	if (cl_chasecam.value) {
		cmd->forwardmove = cmd->sidemove = cmd->upmove = 0;

		VectorCopy(player->viewangles, cl.viewangles);
		VectorCopy(player->origin, desired_position);
		if (memcmp(&desired_position, &self->origin, sizeof(desired_position)) != 0) {
			MSG_WriteByte (&cls.netchan.message, clc_tmove);
			MSG_WriteCoord (&cls.netchan.message, desired_position[0]);
			MSG_WriteCoord (&cls.netchan.message, desired_position[1]);
			MSG_WriteCoord (&cls.netchan.message, desired_position[2]);
			// move there locally immediately
			VectorCopy(desired_position, self->origin);
		}
		self->weaponframe = player->weaponframe;

	} else {
		// Ok, move to our desired position and set our angles to view
		// the player
		VectorSubtract(desired_position, self->origin, vec);
		len = vlen(vec);
		cmd->forwardmove = cmd->sidemove = cmd->upmove = 0;
		if (len > 16) { // close enough?
			MSG_WriteByte (&cls.netchan.message, clc_tmove);
			MSG_WriteCoord (&cls.netchan.message, desired_position[0]);
			MSG_WriteCoord (&cls.netchan.message, desired_position[1]);
			MSG_WriteCoord (&cls.netchan.message, desired_position[2]);
		}

		// move there locally immediately
		VectorCopy(desired_position, self->origin);
										 
		VectorSubtract(player->origin, desired_position, vec);
		vectoangles(vec, cl.viewangles);
		cl.viewangles[0] = -cl.viewangles[0];
	}
}
Пример #29
0
static void zpr_motion(int x, int y) {
  bool changed = false;

  const int dx = x - _mousex;
  const int dy = y - _mousey;

  GLint viewport[4];
  glGetIntegerv(GL_VIEWPORT, viewport);

  if(dx == 0 && dy == 0) return;

  if(_mouse_middle || _mouse_right) {
    double s = exp((double)dy * 0.01);

    glTranslatef(zpr_reference_point[0], zpr_reference_point[1], zpr_reference_point[2] );
    glscale *= s;
    glScalef(s, s, s);
    glTranslatef(zpr_reference_point[0], zpr_reference_point[1], zpr_reference_point[2]);

    changed = true;
  }
  else if(_mouse_left) {
    double ax, ay, az;
    double bx, by, bz;
    double angle;

    ax = dy;
    ay = dx;
    az = 0.0;
    angle = vlen(az, ay, az) / (double)(viewport[2]+1)*180.0;

    // Use inverse matrix to determine axis of rotation.
    bx = _matrix_inverse[0] * ax + _matrix_inverse[4] * ay + _matrix_inverse[8]   * az;
    by = _matrix_inverse[1] * ax + _matrix_inverse[5] * ay + _matrix_inverse[9]   * az;
    bz = _matrix_inverse[2] * ax + _matrix_inverse[6] * ay + _matrix_inverse[10]  * az;

    glTranslatef(zpr_reference_point[0], zpr_reference_point[1], zpr_reference_point[2]);
    glRotatef(angle, bx, by, bz);
    glTranslatef(zpr_reference_point[0], zpr_reference_point[1], zpr_reference_point[2]);

    changed = true;
  }
  else if(0 && _mouse_right) {
    double px, py, pz;

    pos(&px, &py, &pz, x, y, viewport);

    glLoadIdentity();
    glTranslatef(px - _drag_posx, py - _drag_posy, pz - _drag_posz);
    glMultMatrixd(_matrix);

    _drag_posx = px;
    _drag_posy = py;
    _drag_posz = pz;

    changed = true;
  }
  _mousex = x;
  _mousey = y;

  if(changed) {
    reset_orientation = 0;
    get_matrix();
    glutPostRedisplay();
  }
}
double angle_sin(point3 l1,point3 l2,point3 s1,point3 s2,point3 s3)
{
	return dmult(subt(l1,l2),pvec(s1,s2,s3))/vlen(subt(l1,l2))/vlen(pvec(s1,s2,s3));
}