//--------------------------------------------------------------------- // Refresh location //--------------------------------------------------------------------- void CFuiWeatherView::EditLocation() { CmHead *apt = globals->dbc->FindFirstNearest(APT); if (0 == apt) return NoLocation(); float dx = apt->GetDistLon() / 128; float dy = apt->GetDistLat() / 128; float dis = SquareRootFloat((dx*dx)+(dy*dy)); disW->EditText("%.2f miles from ",dis); locW->SetText (apt->GetName()); return; }
/* ================ CM_TraceThroughSphere get the first intersection of the ray with the sphere ================ */ static void CM_TraceThroughSphere(traceWork_t *tw, vec3_t origin, float radius, vec3_t start, vec3_t end) { float l1, l2, length; float /*a, */ b, c, d; vec3_t v1, dir; // if inside the sphere VectorSubtract(start, origin, dir); l1 = VectorLengthSquared(dir); if (l1 < Square(radius)) { tw->trace.fraction = 0; tw->trace.startsolid = qtrue; // test for allsolid VectorSubtract(end, origin, dir); l1 = VectorLengthSquared(dir); if (l1 < Square(radius)) { tw->trace.allsolid = qtrue; } return; } VectorSubtract(end, start, dir); length = VectorNormalize(dir); l1 = CM_DistanceFromLineSquared(origin, start, end, dir); VectorSubtract(end, origin, v1); l2 = VectorLengthSquared(v1); // if no intersection with the sphere and the end point is at least an epsilon away if (l1 >= Square(radius) && l2 > Square(radius + SURFACE_CLIP_EPSILON)) { return; } // | origin - (start + t * dir) | = radius // a = dir[0]^2 + dir[1]^2 + dir[2]^2; // b = 2 * (dir[0] * (start[0] - origin[0]) + dir[1] * (start[1] - origin[1]) + dir[2] * (start[2] - origin[2])); // c = (start[0] - origin[0])^2 + (start[1] - origin[1])^2 + (start[2] - origin[2])^2 - radius^2; VectorSubtract(start, origin, v1); // dir is normalized so a = 1 //a = 1.0f; //dir[0] * dir[0] + dir[1] * dir[1] + dir[2] * dir[2]; b = 2.0f * (dir[0] * v1[0] + dir[1] * v1[1] + dir[2] * v1[2]); c = v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2] - (radius + RADIUS_EPSILON) * (radius + RADIUS_EPSILON); d = b * b - 4.0f * c; // * a; if (d > 0) { vec3_t intersection; float sqrtd = SquareRootFloat(d); // = (- b + sqrtd) * 0.5f; // / (2.0f * a); float fraction = (-b - sqrtd) * 0.5f; // / (2.0f * a); if (fraction < 0) { fraction = 0; } else { fraction /= length; } if (fraction < tw->trace.fraction) { float scale; tw->trace.fraction = fraction; VectorSubtract(end, start, dir); VectorMA(start, fraction, dir, intersection); VectorSubtract(intersection, origin, dir); #ifdef CAPSULE_DEBUG l2 = VectorLength(dir); if (l2 < radius) { int bah = 1; } #endif scale = 1 / (radius + RADIUS_EPSILON); VectorScale(dir, scale, dir); VectorCopy(dir, tw->trace.plane.normal); VectorAdd(tw->modelOrigin, intersection, intersection); tw->trace.plane.dist = DotProduct(tw->trace.plane.normal, intersection); tw->trace.contents = CONTENTS_BODY; } } /* else if (d == 0) { //t1 = (- b ) / 2; // slide along the sphere } */ // no intersection at all }
/* ================ CM_TraceThroughVerticalCylinder get the first intersection of the ray with the cylinder the cylinder extends halfheight above and below the origin ================ */ static void CM_TraceThroughVerticalCylinder(traceWork_t *tw, vec3_t origin, float radius, float halfheight, vec3_t start, vec3_t end) { float length, l1, l2; float /*a, */ b, c, d; vec3_t v1, dir, start2d, end2d, org2d; // 2d coordinates VectorSet(start2d, start[0], start[1], 0); VectorSet(end2d, end[0], end[1], 0); VectorSet(org2d, origin[0], origin[1], 0); // if between lower and upper cylinder bounds if (start[2] <= origin[2] + halfheight && start[2] >= origin[2] - halfheight) { // if inside the cylinder VectorSubtract(start2d, org2d, dir); l1 = VectorLengthSquared(dir); if (l1 < Square(radius)) { tw->trace.fraction = 0; tw->trace.startsolid = qtrue; VectorSubtract(end2d, org2d, dir); l1 = VectorLengthSquared(dir); if (l1 < Square(radius)) { tw->trace.allsolid = qtrue; } return; } } // VectorSubtract(end2d, start2d, dir); length = VectorNormalize(dir); // l1 = CM_DistanceFromLineSquared(org2d, start2d, end2d, dir); VectorSubtract(end2d, org2d, v1); l2 = VectorLengthSquared(v1); // if no intersection with the cylinder and the end point is at least an epsilon away if (l1 >= Square(radius) && l2 > Square(radius + SURFACE_CLIP_EPSILON)) { return; } // (start[0] - origin[0] - t * dir[0]) ^ 2 + (start[1] - origin[1] - t * dir[1]) ^ 2 = radius ^ 2 // (v1[0] + t * dir[0]) ^ 2 + (v1[1] + t * dir[1]) ^ 2 = radius ^ 2; // v1[0] ^ 2 + 2 * v1[0] * t * dir[0] + (t * dir[0]) ^ 2 + // v1[1] ^ 2 + 2 * v1[1] * t * dir[1] + (t * dir[1]) ^ 2 = radius ^ 2 // t ^ 2 * (dir[0] ^ 2 + dir[1] ^ 2) + t * (2 * v1[0] * dir[0] + 2 * v1[1] * dir[1]) + // v1[0] ^ 2 + v1[1] ^ 2 - radius ^ 2 = 0 VectorSubtract(start, origin, v1); // dir is normalized so we can use a = 1 //a = 1.0f; // * (dir[0] * dir[0] + dir[1] * dir[1]); b = 2.0f * (v1[0] * dir[0] + v1[1] * dir[1]); c = v1[0] * v1[0] + v1[1] * v1[1] - (radius + RADIUS_EPSILON) * (radius + RADIUS_EPSILON); d = b * b - 4.0f * c; // * a; if (d > 0) { float sqrtd = SquareRootFloat(d); // = (- b + sqrtd) * 0.5f;// / (2.0f * a); float fraction = (-b - sqrtd) * 0.5f; // / (2.0f * a); if (fraction < 0) { fraction = 0; } else { fraction /= length; } if (fraction < tw->trace.fraction) { vec3_t intersection; VectorSubtract(end, start, dir); VectorMA(start, fraction, dir, intersection); // if the intersection is between the cylinder lower and upper bound if (intersection[2] <= origin[2] + halfheight && intersection[2] >= origin[2] - halfheight) { float scale; tw->trace.fraction = fraction; VectorSubtract(intersection, origin, dir); dir[2] = 0; #ifdef CAPSULE_DEBUG l2 = VectorLength(dir); if (l2 <= radius) { int bah = 1; } #endif scale = 1 / (radius + RADIUS_EPSILON); VectorScale(dir, scale, dir); VectorCopy(dir, tw->trace.plane.normal); VectorAdd(tw->modelOrigin, intersection, intersection); tw->trace.plane.dist = DotProduct(tw->trace.plane.normal, intersection); tw->trace.contents = CONTENTS_BODY; } } } /* else if (d == 0) { //t[0] = (- b ) / 2 * a; // slide along the cylinder } */ // no intersection at all }
//--------------------------------------------------------------- // Ground (X,Y) Distance to V //--------------------------------------------------------------- float CVector::GroundDistance(SVector &v) { double dx = (x - v.x); double dy = (y - v.y); float sq = ((dx*dx) + (dy*dy)); return SquareRootFloat(sq); }
//--------------------------------------------------------------- // Distance to V //--------------------------------------------------------------- double CVector::DistanceTo(SVector &v) { double dx = x - v.x; double dy = y - v.y; double dz = z - v.z; return SquareRootFloat((dx*dx) + (dy*dy) + (dz*dz)); }
//-------------------------------------------------------------------------- float CVector::FastLength() { double dg = (x*x) + (y*y) + (z*z); return SquareRootFloat(dg); }
void CLocalFrame::ipos2geop (const CVector &ipos, SPosition &geop) { // update earth rotation = aE if_.GetEarthRotationSinCos (); CVector epos; // position in eath-fixed cartesian coordinates // calculate epos - rotation aE radians about z-axis epos.x = ipos.x * if_.GetCosAE () + ipos.y * if_.GetSinAE (); epos.y = -ipos.x * if_.GetSinAE () + ipos.y * if_.GetCosAE (); epos.z = ipos.z; // #ifdef _DEBUG_FRAME_MANAGER { FILE *fp_debug; if(!(fp_debug = fopen("__DDEBUG_frames.txt", "a")) == NULL) { fprintf(fp_debug, "ipos.x %.2f ipos.y %.2f ipos.z %.2f epos.x %.2f epos.y %.2f epos.z %.2f\n", ipos.x, ipos.y, ipos.z, epos.x, epos.y, epos.z ); fclose(fp_debug); } } #endif // calculate altitude // the distance r from the center of the earth is the length // of the position vector. ipos is beter because it's the master // pos so we don't introduce any rounding error from epos // NB: We are ignoring the fact that the earth is not a perfect // sphere for now - This is hard enough as it is already. double r = SquareRootFloat (ipos.x * ipos.x + ipos.y * ipos.y + ipos.z * ipos.z); geop.alt = MetresToFeet (r - EARTH_RADIUS_SI); // altitude in metres-->feet // calculate latitude and longitude // = transformation in polar coordinates // latitude is the "up" angle from equator // longitude is the angle east from 0N0E geop.lat = 0.0; geop.lon = 0.0; if (r) { double latRad = safeAsin (ipos.z / r); // lat in rad //double latRad = atan2 (ipos.z, r); // lat in rad double lonRad = atan2 (epos.y, epos.x); // lon in rad, east is positive // #ifdef _DEBUG_FRAME_MANAGER { FILE *fp_debug; if(!(fp_debug = fopen("__DDEBUG_frames.txt", "a")) == NULL) { fprintf(fp_debug, "geop.x %.2f geop.y %.2f geop.z %.2f\n", latRad, lonRad, geop.alt ); fclose(fp_debug); } } #endif // convert to arcsec // Even thinks we'd use meters above MSL geop.lat = radians2arcseconds_lat (latRad); geop.lon = radians2arcseconds_lon (lonRad); } }
static void CM_TraceThroughLeaf( traceWork_t* tw, const cLeaf_t* leaf ) { int k; int brushnum; cbrush_t *b; cPatch_t *patch; // trace line against all brushes in the leaf for ( k = 0 ; k < leaf->numLeafBrushes ; k++ ) { brushnum = cm.leafbrushes[leaf->firstLeafBrush+k]; b = &cm.brushes[brushnum]; if ( b->checkcount == cm.checkcount ) { continue; // already checked this brush in another leaf } b->checkcount = cm.checkcount; if ( !(b->contents & tw->contents) ) { continue; } if (!CM_BoundsIntersect( tw->bounds[0], tw->bounds[1], b->bounds[0], b->bounds[1] )) continue; CM_TraceThroughBrush( tw, b ); if ( !tw->trace.fraction ) { return; } } // trace line against all patches in the leaf #ifdef BSPC if (1) { #else if ( !cm_noCurves->integer ) { #endif for ( k = 0 ; k < leaf->numLeafSurfaces ; k++ ) { patch = cm.surfaces[ cm.leafsurfaces[ leaf->firstLeafSurface + k ] ]; if ( !patch ) { continue; } if ( patch->checkcount == cm.checkcount ) { continue; // already checked this patch in another leaf } patch->checkcount = cm.checkcount; if ( !(patch->contents & tw->contents) ) { continue; } CM_TraceThroughPatch( tw, patch ); if ( !tw->trace.fraction ) { return; } } } } #define RADIUS_EPSILON 1.0f /* ================ CM_TraceThroughSphere get the first intersection of the ray with the sphere ================ */ void CM_TraceThroughSphere( traceWork_t *tw, vec3_t origin, float radius, vec3_t start, vec3_t end ) { float l1, l2, length, scale, fraction; float a, b, c, d, sqrtd; vec3_t v1, dir, intersection; // if inside the sphere VectorSubtract(start, origin, dir); l1 = VectorLengthSquared(dir); if (l1 < Square(radius)) { tw->trace.fraction = 0; tw->trace.startsolid = qtrue; // test for allsolid VectorSubtract(end, origin, dir); l1 = VectorLengthSquared(dir); if (l1 < Square(radius)) { tw->trace.allsolid = qtrue; } return; } // VectorSubtract(end, start, dir); length = VectorNormalize(dir); // l1 = CM_DistanceFromLineSquared(origin, start, end, dir); VectorSubtract(end, origin, v1); l2 = VectorLengthSquared(v1); // if no intersection with the sphere and the end point is at least an epsilon away if (l1 >= Square(radius) && l2 > Square(radius+SURFACE_CLIP_EPSILON)) { return; } // // | origin - (start + t * dir) | = radius // a = dir[0]^2 + dir[1]^2 + dir[2]^2; // b = 2 * (dir[0] * (start[0] - origin[0]) + dir[1] * (start[1] - origin[1]) + dir[2] * (start[2] - origin[2])); // c = (start[0] - origin[0])^2 + (start[1] - origin[1])^2 + (start[2] - origin[2])^2 - radius^2; // VectorSubtract(start, origin, v1); // dir is normalized so a = 1 a = 1.0f;//dir[0] * dir[0] + dir[1] * dir[1] + dir[2] * dir[2]; b = 2.0f * (dir[0] * v1[0] + dir[1] * v1[1] + dir[2] * v1[2]); c = v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2] - (radius+RADIUS_EPSILON) * (radius+RADIUS_EPSILON); d = b * b - 4.0f * c;// * a; if (d > 0) { sqrtd = SquareRootFloat(d); // = (- b + sqrtd) * 0.5f; // / (2.0f * a); fraction = (- b - sqrtd) * 0.5f; // / (2.0f * a); // if (fraction < 0) { fraction = 0; } else { fraction /= length; } if ( fraction < tw->trace.fraction ) { tw->trace.fraction = fraction; VectorSubtract(end, start, dir); VectorMA(start, fraction, dir, intersection); VectorSubtract(intersection, origin, dir); #ifdef CAPSULE_DEBUG l2 = VectorLength(dir); if (l2 < radius) { int bah = 1; } #endif scale = 1 / (radius+RADIUS_EPSILON); VectorScale(dir, scale, dir); VectorCopy(dir, tw->trace.plane.normal); VectorAdd( tw->modelOrigin, intersection, intersection); tw->trace.plane.dist = DotProduct(tw->trace.plane.normal, intersection); tw->trace.contents = CONTENTS_BODY; } } else if (d == 0) { //t1 = (- b ) / 2; // slide along the sphere } // no intersection at all }
gint pixies_main() { int looper, slomo; //System energy is calculated by accumalting the pixies individual energies //i.e. its need to be reset on each loop total_energy = 0; //do-nothing code for slow motion effect slomo = gtk_range_get_value(slomo_slider); for (looper = 0; looper <= slomo*slomo*slomo; looper++){;} //make sure screen is cleared when popultaion is zero if (population == 0) gtk_widget_queue_draw(da); //Main village loop for (looper = 0; looper < population; looper++){ if (active_pixies){ if (!village[looper].static_flag){ //Apply the physical fields ljp(); //Add the direction to their position village[looper].x_position += village[looper].x_direction; village[looper].y_position += village[looper].y_direction; } //Apply cooling or heating if (village[looper].ch_value < 0){ village[looper].x_direction /= abs(village[looper].ch_value); village[looper].y_direction /= abs(village[looper].ch_value); } if (village[looper].ch_value > 0){ village[looper].x_direction *= (village[looper].ch_value / 100) + 1; village[looper].y_direction *= (village[looper].ch_value / 100) + 1; } //Apply Gravity GRAVITY = gtk_range_get_value(gravity_slider); if (village[looper].y_position < screen_width) village[looper].y_direction += GRAVITY; //calculation for total energy value //Oh dear, looks like you need to do some calculus to get this boy working properly... //because force is the GRADIENT of the LJ potential float resolved_speed; resolved_speed = SquareRootFloat( (village[looper].x_direction * village[looper].x_direction ) + (village[looper].y_direction * village[looper].y_direction ) ); total_energy += resolved_speed; //Check for wall-bashing float right_dist, bottom_dist; int gap = 30; right_dist = screen_width - village[looper].x_position; village[looper].x_direction -= 10 / pow( fabs(right_dist - gap), 3); village[looper].x_direction += 10 / pow( fabs(village[looper].x_position - gap), 3); bottom_dist = screen_height - village[looper].y_position; village[looper].y_direction -= 10 / pow( fabs(bottom_dist - gap), 3); village[looper].y_direction += 10 / pow( fabs(village[looper].y_position - gap), 3); /* if (village[looper].x_position <= gap){ village[looper].x_direction = fabs(village[looper].x_direction); } if (village[looper].x_position >= (screen_width - gap) ){ village[looper].x_direction = -fabs(village[looper].x_direction); } if (village[looper].y_position <= gap){ village[looper].y_direction = fabs(village[looper].y_direction); } if (village[looper].y_position >= (screen_height - gap) ){ village[looper].y_direction = -fabs(village[looper].y_direction); } */ } //Provide visual information for screen display x = village[looper].x_position; y = village[looper].y_position; //printf("x%d\n", x ); //printf("y%d\n", y ); //place data to screen BUFFER put_pixel(buffer, x, y, village[looper].color_gtk); put_pixel(buffer, x+1, y, village[looper].color_gtk); put_pixel(buffer, x, y+1, village[looper].color_gtk); put_pixel(buffer, x-1, y, village[looper].color_gtk); put_pixel(buffer, x, y-1, village[looper].color_gtk); if (village[looper].style == SELECTED){ put_pixel(buffer, x, y, village[looper].color_gtk); put_pixel(buffer, x+2, y, village[looper].color_gtk); put_pixel(buffer, x, y+2, village[looper].color_gtk); put_pixel(buffer, x-2, y, village[looper].color_gtk); put_pixel(buffer, x, y-2, village[looper].color_gtk); } //Deal with the Frames Per Second Malarky FPS = gtk_range_get_value(FPS_slider); if ( g_timer_elapsed(FPS_timer, NULL) > (1 / FPS) && looper == population - 1 ){ gtk_widget_queue_draw(da); //update Pixie World labels update_energy_label(); g_timer_reset(FPS_timer); } } return TRUE; }