void Flamer::calculate() { STACKTRACE; if ( !commandship || !ship || !commandship->exists() || !ship->exists() ) { commandship = 0; state = 0; return; } Missile::calculate(); // fix the location and direction of the flame with respect to the ship. double D = ( commandship->get_size().y + get_size().y ) / 2.0; if ( iSide == 1 ) { pos = commandship->pos + D * unit_vector(commandship->angle); vel = commandship->vel; // important for prediction? angle = commandship->angle; } else { pos = commandship->pos - D * unit_vector(commandship->angle); vel = commandship->vel; angle = commandship->angle + PI; } // - 16; sprite_index = get_index(angle, -0.5*PI); sprite_index += sprite_offset * 64; animate_time += frame_time; if ( animate_time > nextpictime ) { animate_time -= nextpictime; sprite_offset += 1; // hard coded ?!?!?! if ( sprite_offset > Nanimatedflame-1 ) sprite_offset = 0; } // the active weapon also has influence on the commandship by providing thrust: // commandship->vel += FlameAccel*unit_vector(angle+PI); commandship->accelerate_gravwhip(this, angle+PI, FlameAccel, MAX_SPEED); // double v = magnitude(commandship->vel); // if ( v > commandship->speed_max ) // commandship->vel *= commandship->speed_max / v; }
void TauMCMissile::calculate() { STACKTRACE; Missile::calculate(); if (state == 0) return; if (target) if ((!target->exists()) || (fabs(get_aim(target)) > track_angle)) target = NULL; if (!target) { Query q; double a_a, a0 = -1e20; for (q.begin(this, OBJECT_LAYERS, range - d); q.currento; q.next()) { if (!q.current->isObject()) continue; if ( (!q.currento->sameTeam(this)) && (q.currento->collide_flag_anyone&bit(layer)) && !q.currento->isPlanet() ) { a_a = fabs(get_aim(q.currento)); if (a_a < 0) continue; if (a_a < track_angle) { a_a = (track_angle - a_a) * ((range - d) - distance(q.currento)) * (1 + (q.currento->isShip()?w_ship:0) + (q.currento->isShot()?w_shot:0) ); if (a_a > a0) { target = q.currento; a0 = a_a; } } } } } if (target && !target->isInvisible()) { double d_a = get_aim(target); double ta = turn_rate * frame_time; if (fabs(d_a) < ta) ta = fabs(d_a); if (d_a > 0) turn_step += ta; else turn_step -= ta; while(fabs(turn_step) > 5.625/2) { if (turn_step < 0.0) { angle -= 5.625; turn_step += 5.625; } else if (turn_step > 0.0) { angle += 5.625; turn_step -= 5.625; } } angle = normalize(angle, 360); } // ? // sprite_index = (int)(angle / 5.625) + 16; // sprite_index &= 63; sprite_index = get_index(angle); //vx = v * cos(angle * ANGLE_RATIO); //vy = v * sin(angle * ANGLE_RATIO); vel = v * unit_vector(angle); }
void UlzrakInterceptor::calculate() { STACKTRACE; double fracDone; if ((!zoomActive) && (!zoomSequenceInitiated)) spriteShift = 0; if (zoomActive) { mass = this->specialZoomMass; if (zoomReversed) this->zoomVel = (-1) * unit_vector(this->angle) * this->specialZoomSpeedAddition; else this->zoomVel = unit_vector(this->angle) * this->specialZoomSpeedAddition; if (this->specialZoomSpeedIsAdditive) set_vel ( this->normalVel + this->zoomVel ); else set_vel ( this->zoomVel ); this->damage_factor = this->specialCollisionDamage; this->zoomCounter += frame_time; this->DrawZoomLines(); spriteShift = 3; if (zoomCounter>=this->specialZoomTime) { UnZoom(); } } else if (zoomCounter >= this->specialActivationTime) { play_sound2((this->data->sampleSpecial[1])); this->zoomActive = true; this->zoomReversed = false; this->zoomSequenceInitiated = false; this->zoomCounter = 0; //storing away the normal Velocity this->normalVel = this->vel; this->zoomVel = unit_vector(this->angle) * this->specialZoomSpeedAddition; this->inflictDamageCounter = 0; } else if (zoomSequenceInitiated) { zoomCounter += frame_time; fracDone = (double)zoomCounter / (double)this->specialActivationTime; spriteShift = (int)((fracDone * 3.0) + 0.5); } sprite_index_override = get_index(this->angle) + 64 * spriteShift; sprite_index = sprite_index_override; Ship::calculate(); sprite_index = sprite_index_override; }
static void project_along(double v[3], const double w[3], const double u[3]) { double uhat[3]; double dp; unit_vector(uhat, u); dp = dot(w, uhat); scale(v, uhat, dp); }
int UmgahDrone::activate_special() { STACKTRACE; special_rate = specialRate; vel = 0; pos -= (unit_vector(angle) * size.x * 2.0); if (!thrust) special_rate = 50; return(TRUE); }
END_TEST START_TEST(test_unit_vec) { vec3d v1 = {1., 100., 1.}, res = {0.0099, 0.9999, 0.0099}, out; unit_vector(v1, out); fail_unless(vec_approx_cmp(out, res, 1e-4)); }
void ChmmrZapSat::calculate() { STACKTRACE; SpaceObject::calculate(); if (!(ship && ship->exists())) { ship = 0; state = 0; return; } // x = ship->normal_x() + (cos(angle) * 100.0); // y = ship->normal_y() + (sin(angle) * 100.0); pos = ship->normal_pos() + unit_vector(angle) * 100.0; double da = 0.002; angle += da * frame_time; // vx = (ship->normal_x() + (cos(angle) * 100.0) - x) / frame_time; // vy = (ship->normal_y() + (sin(angle) * 100.0) - y) / frame_time; vel = (ship->normal_pos() + unit_vector(angle) * 100.0 - pos) / frame_time; if (angle >= PI2) angle -= PI2; sprite_index = get_index(angle); if (lRecharge > 0) { lRecharge -= frame_time; return; } Query q; for (q.begin(this, OBJECT_LAYERS &~ bit(LAYER_CBODIES), lRange); q.currento; q.next()) { if (!q.currento->isInvisible() && !q.currento->sameTeam(this) && (q.currento->collide_flag_anyone&bit(LAYER_LINES))) { add(new PointLaser(this, pallete_color[lColor], 1, lFrames, this, q.currento, Vector2(0.0, 0.0) )); sound.play((SAMPLE *)(melee[MELEE_BOOM + 0].dat)); lRecharge += lRechargeRate; break; } } return; }
void AndrosynthGuardian::inflict_damage(SpaceObject *other) { STACKTRACE; if (damage_factor > 0) { if (other->mass) { game->add(new Animation(this, pos + unit_vector(trajectory_angle(other)) * 20.0, meleedata.sparkSprite, 0, SPARK_FRAMES, 50, DEPTH_EXPLOSIONS)); translate(-specialBounceDistance*unit_vector(angle)); bounce_status = specialBounceTime; int i = iround_down(damage_factor / 2); if (i >= BOOM_SAMPLES) i = BOOM_SAMPLES - 1; play_sound((SAMPLE *)(melee[MELEE_BOOM + i].dat)); } if (!other->isProtected()) damage(other, damage_factor); } else damage(other, 0); return; }
Eigen::Eigen(Matrix const &m) { double const B = -m[0] - m[3]; double const C = m[0]*m[3] - m[1]*m[2]; double const center = -B/2.0; double const delta = sqrt(B*B-4*C)/2.0; values = Point(center + delta, center - delta); for (int i = 0; i < 2; i++) { vectors[i] = unit_vector(rot90(Point(m[0]-values[i], m[1]))); } }
void TauFiend::animate(Frame* space) { STACKTRACE; if (engine_stage > 0) data->spriteExtraExplosion->animate( //normal_x() - (cos(angle * ANGLE_RATIO) * w / 2.8), //normal_y() - (sin(angle * ANGLE_RATIO) * h / 2.8), normal_pos() - unit_vector(angle) * size / 2.8, engine_frame, space); int si = (int)floor((charge_count * 10.0) / charge_time); if (si >= 0) { if (si>9) si = 9; data->spriteExtra->animate( //normal_x() + (cos(angle * ANGLE_RATIO) * w / 2.8), //normal_y() + (sin(angle * ANGLE_RATIO) * h / 2.8), normal_pos() + unit_vector(angle) * size / 2.8, si, space); } Ship::animate(space); }
int TauDagger::activate_special() { STACKTRACE; game->add(new TauDaggerShot(this, Vector2(0,55), angle, specialVelocity, specialDamage, specialRange, specialArmour, data->spriteSpecial)); game->add(new TauDaggerBeam(this, Vector2(15,9), 43.5, 0, 50, angle-19.5*ANGLE_RATIO)); game->add(new TauDaggerBeam(this, Vector2(-15,9), 43.5, 0, 50, angle+19.5*ANGLE_RATIO)); accelerate(this, -unit_vector(angle)*specialRecoil); return true; }
int ChmmrAvatar::activate_weapon() { STACKTRACE; add(new ChmmrLaser(angle, weaponRange, weaponDamage, weapon_rate, this, Vector2(0.0, 25.0) )); if (tw_random(150) < frame_time) { add(new Animation(this, pos + unit_vector(angle) * (tw_random(weaponRange-15) + 25 + 25) + Vector2(tw_random(-25,25), tw_random(-25,25)), data->spriteWeaponExplosion, (random()%4)*10, 10, 25+tw_random(50), DEPTH_EXPLOSIONS, tw_random(1.0) + tw_random(1.0)) ); add(new Animation(this, pos + unit_vector(angle) * (tw_random(weaponRange-15) + 25 + 25) + Vector2(tw_random(-25,25), tw_random(-25,25)), data->spriteWeaponExplosion, (random()%4)*10, 10, 50, DEPTH_EXPLOSIONS) ); } uninterrupted_fire = true; return(TRUE); }
void NisskHarasser::calculate() { STACKTRACE; lastSpecial = currentSpecial; currentSpecial = this->fire_special; oldDriveMode = driveMode; Ship::calculate(); if (debounce>0) { debounce -= frame_time; } if (!specialToggleMode) { if (specialIsInertialess) { //tw_error("special is inertialess!"); if (fire_special) { this->recharge_rate = specialRechargeRate; driveMode = 1; } else { this->recharge_rate = shipRechargeRate; driveMode = 0; } } else { if (fire_special) { this->recharge_rate = shipRechargeRate; driveMode = 0; } else { this->recharge_rate = specialRechargeRate; driveMode = 1 ; } } } if (driveMode==0) { this->recharge_rate = shipRechargeRate; //message.print(1500,9,"recharge_rate = %i", recharge_rate); turn_rate = shipTurnRate; speed_max = shipSpeedMax; sprite_index = get_index(angle) + (0 * 64); return; } else { this->recharge_rate = specialRechargeRate; //message.print(1500,9,"recharge_rate = %i", recharge_rate); turn_rate = specialTurnRate; speed_max = specialSpeedMax; sprite_index = get_index(angle) + (1 * 64); } if (thrust||specialIsAutothrust) { vel = specialSpeedMax * unit_vector(angle); } else vel *= exp(- frame_time * 0.02 ); }
void TauMC::calculate_hotspots() { STACKTRACE; if ((thrust) && (hotspot_frame <= 0)) { add(new Animation(this, //normal_x() - (cos(angle * ANGLE_RATIO) * w / 2.0), //normal_y() - (sin(angle * ANGLE_RATIO) * h / 2.0), normal_pos() - 0.5 * sprite->size().x * unit_vector(angle), meleedata.hotspotSprite, 0, HOTSPOT_FRAMES, time_ratio, LAYER_HOTSPOTS)); hotspot_frame += hotspot_rate; } if (hotspot_frame > 0) hotspot_frame -= frame_time; }
Eigen::Eigen(double m[2][2]) { double const B = -m[0][0] - m[1][1]; double const C = m[0][0]*m[1][1] - m[1][0]*m[0][1]; //double const desc = B*B-4*C; //double t = -0.5*(B+sgn(B)*desc); int n; values[0] = values[1] = 0; quadratic_roots(C, B, 1, n, values[0], values[1]); for (int i = 0; i < n; i++) vectors[i] = unit_vector(rot90(Point(m[0][0]-values[i], m[0][1]))); for (int i = n; i < 2; i++) vectors[i] = Point(0,0); }
/*!\rst Test vector norm. For several problem sizes, check: 1. zeros have ``norm = 0`` 2. ``\|\alpha\| = \alpha`` where \alpha is scalar 3. Scaling a vector by its own norm results in a vector with ``norm = 1.0``. 4. Columns of a matrix whose columns are *known* to have unit-norm. \return number of cases where the norm is wrong \endrst*/ OL_WARN_UNUSED_RESULT int TestNorm() noexcept { int total_errors = 0; const int num_sizes = 3; const int sizes[num_sizes] = {11, 100, 1007}; UniformRandomGenerator uniform_generator(34187); for (int i = 0; i < num_sizes; ++i) { std::vector<double> vector(sizes[i], 0.0); // zero vector has zero norm double norm = VectorNorm(vector.data(), vector.size()); if (!CheckDoubleWithin(norm, 0.0, 0.0)) { ++total_errors; } BuildRandomVector(sizes[i], -1.0, 1.0, &uniform_generator, vector.data()); // norm of nothing element is 0 norm = VectorNorm(vector.data(), 0); if (!CheckDoubleWithin(norm, 0.0, 0.0)) { ++total_errors; } // norm of 1 element is |that element| norm = VectorNorm(vector.data(), 1); if (!CheckDoubleWithinRelative(norm, std::fabs(vector[0]), std::numeric_limits<double>::epsilon())) { ++total_errors; } // unit vectors have unit norm norm = VectorNorm(vector.data(), vector.size()); std::vector<double> unit_vector(vector); VectorScale(unit_vector.size(), 1.0/norm, unit_vector.data()); double unit_norm = VectorNorm(unit_vector.data(), unit_vector.size()); if (!CheckDoubleWithinRelative(unit_norm, 1.0, std::numeric_limits<double>::epsilon())) { ++total_errors; } if (i < num_sizes - 1) { // don't do the largest case std::vector<double> orthogonal_matrix(Square(sizes[i])); BuildOrthogonalSymmetricMatrix(sizes[i], orthogonal_matrix.data()); for (int j = 0; j < sizes[i]; ++j) { double column_norm = VectorNorm(orthogonal_matrix.data() + j*sizes[i], sizes[i]); if (!CheckDoubleWithinRelative(column_norm, 1.0, std::sqrt(static_cast<double>(sizes[i]))*std::numeric_limits<double>::epsilon())) { ++total_errors; } } } } return total_errors; }
Vector2 FopVob::getP(int i) { STACKTRACE; Vector2 P; //double y, t; //t = physics->game_time * 1E-3; //y = specialR * sin(PI2 * (t - T0[i]) / specialPeriod); P = getY(i) * unit_vector(angle); return P; }
void JyglarStarfarer::calculate_hotspots() { STACKTRACE; if ( thrust && hotspot_frame <= 0 ) { game->add( new Animation( this, normal_pos() - unit_vector(angle) * size.y / 4, data->spriteExtra, 0, data->spriteExtra->frames(), time_ratio, LAYER_HOTSPOTS)); hotspot_frame += hotspot_rate; } if ( hotspot_frame > 0 ) hotspot_frame -= frame_time; }
void TauFiend::calculate_hotspots() { STACKTRACE; if ((engine_stage > 0) && (hotspot_frame <= 0)) { int f1 = int((HOTSPOT_FRAMES-1)*(7.0 - engine_stage)/6); add(new Animation(this, //normal_x() - (cos(angle * ANGLE_RATIO) * w / 2.8), //normal_y() - (sin(angle * ANGLE_RATIO) * h / 2.8), normal_pos() - unit_vector(angle) * size / 2.8, meleedata.hotspotSprite, f1, HOTSPOT_FRAMES -f1, time_ratio, LAYER_HOTSPOTS)); hotspot_frame += hotspot_rate; } if (hotspot_frame > 0) hotspot_frame -= frame_time; }
void ChmmrAvatar::calculate() { STACKTRACE; Ship::calculate(); if ((uninterrupted_fire) && ((!fire_weapon) || weapon_low)) { uninterrupted_fire = false; add(new Animation(this, pos + unit_vector(angle) * (tw_random(weaponRange-15) + 25 + 25) + Vector2(tw_random(-25,25), tw_random(-25,25)), data->spriteWeaponExplosion, (random()%4)*10, 10, 75, DEPTH_EXPLOSIONS)); }; }
void LaserArc::update_lasersegs() { STACKTRACE; int i; double angle_step; angle_step = (angle_max - angle_min) / Nseg; for ( i = 0; i < Nseg; ++i ) { if ( laser_o[i] && !laser_o[i]->exists() ) laser_o[i] = 0; if (!laser_o[i]) { tw_error("LaserArc: laser segment has died."); } double a, a1, a2, L; a1 = mother->angle + angle_min + i * angle_step; a2 = a1 + angle_step; Vector2 rpos1, rpos2; rpos1 = R * unit_vector(a1); rpos2 = R * unit_vector(a2); a = (rpos2 - rpos1).atan(); L = (rpos2 - rpos1).magnitude(); laser_o[i]->set_props(pos + rpos1, a, L); // just in case someone changes frame_time ? // also, it should depend on the laser seg ( the close they are together, // the bigger the chance that 2 segments will hit). Default damage is for // a laser of length 1 for 1 second. laser_o[i]->damage_factor = mother->specialDamage * frame_time*1E-3 * L / 1.0; // this is damage per second } }
/** void circle3d(WSGraph vp, vector ox, vector ex, int rr, int cc, int mode) 3D的な円の描画. @param gd 操作対象となるグラフィックデータ構造体. @param ox 円の中心の座標ベクトル. @param ex 円の中心の法線ベクトル. @param rr 円の半径. @param cc 線の濃度. @param mode @b ON なら円の内部の 0〜ccを ccで塗りつぶす. */ void circle3d(WSGraph gd, vector ox, vector ex, int rr, int cc, int mode) { vector oz; WSGraph vp; vp = make_WSGraph(2*rr+3, 2*rr+3, 1); if (vp.gp==NULL) return; circle(vp, rr+1, rr+1, rr, cc, mode); oz = set_vector((float)((vp.xs-1)/2.), (float)((vp.ys-1)/2.), 0.0); ex = unit_vector(ex); local2world(gd, vp, ox, oz, ex, NULL, NULL); free(vp.gp); }
/************************************************ || ray_from_eye_throug() || Purpose: calculate a ray for the current pixel ************************************************/ Ray ray_from_eye_through(Vector curPixel) { Ray tempRay; //Camera tempRay.u.x = 0; tempRay.u.y = 0; tempRay.u.z = 1; tempRay.u.w = 1; tempRay.v=unit_vector(vector_subtract(curPixel , tempRay.u)); //printf("\nUnit Vector\nX: %f, Y: %f, Z: %f\n", tempRay.v.x, tempRay.v.y, tempRay.v.z); //printf("\nX: %f, Y: %f, Z: %f\n", tempRay.v.x, tempRay.v.y, tempRay.v.z); return tempRay; }
void NaroolLurker::inflict_damage(SpaceObject *other) { STACKTRACE; Ship::inflict_damage(other); //you've hit something; activate sparks. sparktime = maxsparktime; // but, where did you hit it ? // place the source somewhere... at the edge .. how ? double a, R; a = trajectory_angle(other); R = 40; sparkpos = R * unit_vector(a); sparkpos += 0.5 * Vector2(lightningbmp->w,lightningbmp->h); }
BasiliskAreaHurt::BasiliskAreaHurt(Vector2 opos, double ov, int onum, int olife, int ocolor) : Presence(), num(onum), lifetime(olife), life_counter(0), color(ocolor) { STACKTRACE; if (onum <= 0) { state = 0; return; } set_depth(DEPTH_EXPLOSIONS); xp = new Vector2[num]; xv = new Vector2[num]; int i; for (i=0; i<num; i++) { xp[i] = opos; xv[i] = ov * (0.5+sqrt(sqrt((random()%1000000001)/1000000000.0))) * unit_vector(PI2 * (random()%1000000)/1000000.0); } }
int VirtaoLimb::activate_special() { STACKTRACE; int fire = FALSE; Query q; for (q.begin(this, ALL_LAYERS, specialRange);q.current;q.next()) { if (q.current->canCollide(this)) { double a = trajectory_angle(q.current); q.current->translate(specialPower * unit_vector(a)); fire = TRUE; } } q.end(); if (fire) play_sound((SAMPLE *)(melee[MELEE_BOOM + 0].dat)); return(fire); }
JyglarBubble::JyglarBubble( SpaceLocation *creator, double odist, double odangle, SpaceSprite *osprite, double omass ): SpaceObject( creator, creator->normal_pos() + odist * unit_vector( (creator->get_angle() + odangle) ), creator->get_angle() + odangle, osprite ) { STACKTRACE; layer = LAYER_SPECIAL; mass = omass; dist = odist; dangle = odangle; vel = ship->get_vel(); sprite_index = get_index(angle); countdown = 1000 + random(2000); isblockingweapons = true; attributes &= ~ATTRIB_STANDARD_INDEX; }
Hook2::Hook2(SefyNautilus2 *creator, Vector2 orelpos, SpaceSprite *osprite, bool bHit) : SpaceObject(creator, creator->pos+orelpos, creator->angle, osprite) { STACKTRACE; // double specialRange, specialDelay // ; sprite_index = get_index(angle); // velocity of the ejected hook (0.5). ejvel = creator->specialRelVelocity; // this is in ms vel = ship->vel + ejvel * unit_vector(ship->angle); armour = creator->specialArmour; Nnodes = 0; roll_time = 0; exist_time = 0; life_time = creator->specialLifeTime; oscperiod = creator->specialOscFreq; ropestart = 20.0; // minimum pixels length of a rope segment, approx. ropeseglen = creator->specialSegLength; hooktarget = 0; hooklocked = 0; bHitAsteroids = bHit; springconst = creator->specialSprConst; hooksize = 9; // from center to the eye for the rope. layer = LAYER_SHOTS; set_depth(DEPTH_SHOTS); collide_flag_anyone = ALL_LAYERS; collide_flag_sameteam = ALL_LAYERS; collide_flag_sameship = ALL_LAYERS; isblockingweapons = false; }
vec3 color(const ray& r, surface* world, int depth) { hit_record rec; if (world->hit(r, 0.001, DBL_MAX, rec)) { ray scattered; vec3 attenuation; if (depth < MAXDEPTH && rec.mat_ptr->scatter(r, rec, attenuation, scattered)) { return attenuation*color(scattered, world, depth+1); } else { return vec3(0, 0, 0); } } else { vec3 unit_direction = unit_vector(r.direction()); double t = 0.5*(unit_direction.y() + 1.0); return (1.0 - t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); } }
BChain::BChain(SpaceLocation *creator, Vector2 opos, double oangle, SpaceSprite *osprite, int oSegs,double ospacing, double omass, double ohealth, double om_h_f_t, double oh_d, double of) : Seg(creator,opos, oangle,osprite,NULL,NULL) { STACKTRACE; health = ohealth; max_health = ohealth; friction = of; max_hurt_flash_time = om_h_f_t; hurt_damage = oh_d; hurty_time = 0; Prev_Seg=(Seg *)creator; //Attach the first Seg to the ship mass=omass; Seg *Cur_Seg=this; //Move this pointer to the first Seg Seg_Distance=ospacing; //Each new Seg is placed (ospacing) far away from the previous, //forming an angled line. Vector2 dd = - Seg_Distance * unit_vector(oangle); //Loop that creates all the other Segs for(int num=1; num<oSegs; num++) { //Calculate position of new Seg Vector2 ppos = dd*num + opos; //Create a new Seg that knows that it's attached to Cur_Seg Cur_Seg->Next_Seg = new BasiLink(creator,ppos,oangle,osprite, Cur_Seg,NULL,omass, ohealth, ohealth, om_h_f_t, oh_d, of); //Add it to the game add(Cur_Seg->Next_Seg); //Move the pointer to the new Seg Cur_Seg=Cur_Seg->Next_Seg; } }