bool separate_ball_from_segment(long double *x, long double *y, long double d, segment *seg){ long double dist = point_distance_from_line(*x, *y, &seg->line_equation); if(dist == -1){ return separate_ball_from_fixed_ball(x, y, seg->A.x, seg->A.y, d); }else{ if(dist < d){ long double ang = vector_angle(seg->line_equation.A, seg->line_equation.B), cs = cos(ang); ang = sin(ang); point helpy = {*x + 2 * d * cs, *y + 2 * d * ang}, begin = {*x, *y}; d -= dist; if(do_segments_intersect(&seg->A, &seg->B, &helpy, &begin)){ *x -= d * cs; *y -= d * ang; //-ang }else{ *x += d * cs; *y += d * ang; //ang } return true; }else{ return false; } } }
int lua_CalcAngle( void* l ){ float uv[3],pv[3]; bool isok = true; if( Lua_isnumber(l,1) ){ uv[0] = (float)Lua_tonumber(l,1); }else isok = false; if( Lua_isnumber(l,2) ){ uv[1] = (float)Lua_tonumber(l,2); }else isok = false; if( Lua_isnumber(l,3) ){ uv[2] = (float)Lua_tonumber(l,3); }else isok = false; if( Lua_isnumber(l,4) ){ pv[0] = (float)Lua_tonumber(l,4); }else isok = false; if( Lua_isnumber(l,5) ){ pv[1] = (float)Lua_tonumber(l,5); }else isok = false; if( Lua_isnumber(l,6) ){ pv[2] = (float)Lua_tonumber(l,6); }else isok = false; if( isok ){ double a = vector_angle(uv,pv); a *= 180/M_PI; Lua_pushnumber( l,a ); return 1; } Lua_pushnil(l); return 1; }
//计算x,y,z和你的角度a=GetAngle(x,y,z) int lua_GetAngle( void* l ){ float uv[3],pv[3],av[3],sv[3]; bool isok = true; if( Lua_isnumber(l,1) ){ uv[0] = (float)Lua_tonumber(l,1); }else isok = false; if( Lua_isnumber(l,2) ){ uv[1] = (float)Lua_tonumber(l,2); }else isok = false; if( Lua_isnumber(l,3) ){ uv[2] = (float)Lua_tonumber(l,3); }else isok = false; if( isok ){ size_t len; const char * name = Lua_tolstring(l,1,&len); void* pplayer = GetUnitByName(sPlayer); if( pplayer ){ GetUnitPosition( pplayer,pv ); GetUnitDirection( pplayer,av ); vector_sub( sv,uv,pv ); sv[2] = 0; double a = vector_angle(av,sv); a *= 180/M_PI; Lua_pushnumber( l,a ); return 1; } } Lua_pushnil(l); return 1; }
long double check_exit(long double dx, long double dy, fixed_exit *ex){ long double fi = vector_angle(dx, dy); if(sqrt(dx * dx + dy * dy) - radius_rectangle(ex, fi) < 0){ return 0.01; } else{ return EMPTY_COLLISION_TIME; } }
Vector vector_interpolate_spherical(Vector a, Vector b, float t) { float phi = vector_angle(a, b); float s = sin(phi); float factor_a = sin((1 - t) * phi) / s; float factor_b = sin(t * phi) / s; return vector_add(vector_scale(a, factor_a), vector_scale(b, factor_b)); }
/** I treat fixed points as ininitely small balls */ void get_velocity_after_ball_to_fixed_ball_collision(long double *vx, long double *vy, long double dx, long double dy, long double dr, long double restitution){ long double ang = vector_angle(dx, dy), cs = cos(ang); ang = sin(ang); long double v_into = *vx * cs + *vy * ang, v_perp = *vy * cs - *vx * ang; v_into += dr * sign(v_into); v_into *= -restitution; *vx = v_into * cs - v_perp * ang; *vy = v_into * ang + v_perp * cs; }
/** x1, y1 - coordinates of movable x2, y2 - coordinates of fixed ball d - sum of radiuses Of course works also for fixed points */ bool separate_ball_from_fixed_ball(long double *x1, long double *y1, long double x2, long double y2, long double d){ long double dx = x2 - *x1, dy = y2 - *y1, ang = vector_angle(dx, dy); dx = sqrt(dx * dx + dy * dy); if(dx < d){ d -= dx; //for some reason it doesn't work without: d *= 1.01; d += 1.3; *x1 -= d * cos(ang); *y1 -= d * sin(ang); return true; } return false; }
/** Colliding */ void get_velocities_after_two_balls_collision(long double *v1x, long double *v1y, long double *v2x, long double *v2y, long double dx, long double dy, long double m1, long double m2, long double dr, long double restitution){ *v1x -= *v2x; *v1y -= *v2y; dy = vector_angle(dx, dy); dx = cos(dy); dy = sin(dy); long double v_into = *v1x * dx + *v1y * dy, v_perp = *v1y * dx - *v1x * dy, mc = m1 + m2; v_into += dr * sign(v_into); *v1x = v_into * ((m1 - restitution * m2) / mc); *v1y = *v1x * dy + *v2y + v_perp * dx; *v1x = *v1x * dx + *v2x - v_perp * dy; v_perp = (((1 + restitution) * m1) / mc) * v_into; *v2x += v_perp * dx; *v2y += v_perp * dy; }
/** Separating */ bool separate_two_balls(long double *x1, long double *y1, long double m1, long double *x2, long double *y2, long double m2, long double d){ long double dx = *x2 - *x1, dy = *y2 - *y1, ang = vector_angle(dx, dy); dx = sqrt(dx * dx + dy * dy); if(dx < d){ d -= dx; dx = d * sin(ang); //y d *= cos(ang); //x ang = m1 + m2; dy = m1 / ang; //m1 mass factor ang = m2 / ang; //m2 mass factor *x1 -= d * ang; *y1 -= dx * ang; *x2 += d * dy; *y2 += dx * dy; return true; } return false; }
void test_vector() { Vector *v = vector_new(1,2,3); CU_ASSERT(v->x == 1); CU_ASSERT(v->y == 2); CU_ASSERT(v->z == 3); Vector *vc = vector_copy(v); CU_ASSERT(vc->x == 1); CU_ASSERT(vc->y == 2); CU_ASSERT(vc->z == 3); Vector *u = vector_new(4,5,6); vector_add(v,u); CU_ASSERT(v->x == 5); CU_ASSERT(v->y == 7); CU_ASSERT(v->z == 9); vector_subtract(v,u); CU_ASSERT(v->x == 1); CU_ASSERT(v->y == 2); CU_ASSERT(v->z == 3); vector_multiply(v,2); CU_ASSERT(v->x == 2); CU_ASSERT(v->y == 4); CU_ASSERT(v->z == 6); Vector *w = vector_cross(v,u); CU_ASSERT(w->x == -6); CU_ASSERT(w->y == 12); CU_ASSERT(w->z == -6); vector_free(v); vector_free(u); vector_free(w); v = vector_new(3,4,0); u = vector_new(0,3,4); CU_ASSERT(v->x==u->y); CU_ASSERT(v->y==u->z); w = vector_cross(v,u); CU_ASSERT(w->x == 16); CU_ASSERT(w->y == -12); CU_ASSERT(w->z == 9); CU_ASSERT(within_tol(vector_magnitude(v),5)); CU_ASSERT(within_tol(vector_magnitude(u),5)); vector_free(v); vector_free(u); vector_free(w); v = vector_new(1,0,0); u = vector_new(0,0,1); double a = vector_angle(v,u)/D2R; CU_ASSERT(within_tol(a,90)); CU_ASSERT(within_tol(vector_angle(u,v),90.*D2R)); w = vector_cross(v,u); CU_ASSERT(within_tol(vector_magnitude(w),1)); CU_ASSERT(w->x==0); CU_ASSERT(w->y==-1); CU_ASSERT(w->z==0); }
static void test_vector_angle() { assert_within_delta(0.01, PI*0.25, vector_angle((Vector){ 1, 1 })); }
bool intersection_test(const Bounding *b1, const Bounding *b2, double *intersection_time) { assert(b1 && b2 && "Bad bounding pointers."); assert(intersection_time && "Bad intersection time pointer."); *intersection_time = nan(NULL); if (bounding_composite == b2->bounding_type && bounding_composite != b1->bounding_type) { const Bounding *t = b1; b1 = b2; b2 = t; } if (bounding_composite == b1->bounding_type) { size_t intersections_count = b1->data.composite_data.children_count; double *intersection_times = _alloca(intersections_count * sizeof(double)); // compiler bug? bool *intersection_facts = _alloca(intersections_count * sizeof(bool)); // compiler bug? bool composite_intersection_result = false; for (size_t i = 0; i < intersections_count; i++) { intersection_times[i] = nan(NULL); intersection_facts[i] = intersection_test(b2, &b1->data.composite_data.children[i], &intersection_times[i]); composite_intersection_result |= intersection_facts[i]; } *intersection_time = __get_min_intersection_time(intersection_times, intersection_facts, intersections_count); return composite_intersection_result; } assert(bounding_composite != b1->bounding_type && bounding_composite != b2->bounding_type && "Can't test composite boundings."); Vector axes[6]; double intersection_times[15]; // 6 + 3 * 3. bool intersection_facts[15]; __bounding_get_intersection_axes(b1, &axes[0]); __bounding_get_intersection_axes(b2, &axes[3]); bool intersection_result = true; for (size_t i = 0; i < 6; i++) { intersection_times[i] = nan(NULL); intersection_facts[i] = __bounding_axis_test(b1, b2, &axes[i], &intersection_times[i]); intersection_result &= intersection_facts[i]; } size_t intersection_times_counter = 6; for (size_t i = 0; i < 3; i++) { for (size_t j = 3; j < 6; j++) { if (vector_eq(&axes[i], &axes[j])) { continue; } Vector t; if (!(vector_tolerance_eq(0.0, vector_angle(&axes[i], &axes[j])) || vector_tolerance_eq(M_PI, vector_angle(&axes[i], &axes[j])))) { vector_vector_mul(&axes[i], &axes[j], &t); } else { vector_get_orthogonal(&axes[i], &t); } VECTOR_NORMALIZE(&t); intersection_facts[intersection_times_counter] = __bounding_axis_test(b1, b2, &t, &intersection_times[intersection_times_counter]); intersection_result &= intersection_facts[intersection_times_counter]; intersection_times_counter++; } } *intersection_time = __get_min_intersection_time(intersection_times, intersection_facts, intersection_times_counter); return intersection_result; }
int main(void) { system_init(); printf ("\n\n****************************************************************************************************************\n"); while (1) { frequency_input(); // printf ("V_s_an: %6.2f i_s_an: %6.2f psi_s_an: %6.2f hall_angle: %6.2f freq: %6.2f U_d: %6.2f\n", cita_V_s,cita_i_s, vector_angle(psi_sQ,psi_sD), angle_hall1,CUR_FREQ,U_d); //------------------------------------------------------------------------------ if (print_current==true ) { current_counter=1; printf ("\n\n****************************************************************************************************************\n"); while (current_counter<SAMPLES-2) { //printf("\n %d %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f ",current_counter,current_data_i_sA[current_counter],current_data_i_sB[current_counter],-current_data_i_sA[current_counter]-current_data_i_sB[current_counter],U_d*switching_data_SA[current_counter],U_d*switching_data_SB[current_counter],U_d*switching_data_SC[current_counter]); if (print_selection==0) { printf (":t:%5d:freq: %6.2f :i_sA: %6.2f :i_sB: %6.2f :i_sD: %6.2f :i_sQ: %6.2f :i_s: %6.2f :cita_i_s: %6.2f :U_d: %6.2f \n",timer[current_counter], data_CUR_FREQ[current_counter],data_i_sA[current_counter],data_i_sB[current_counter],data_i_sD[current_counter],data_i_sQ[current_counter],data_i_s[current_counter],data_cita_i_s[current_counter],data_U_d[current_counter]); } else if (print_selection==1) { printf ("freq: %6.2f V_sA: %6.2f V_sB: %6.2f VsC: %6.2f V_sD: %6.2f V_sQ: %6.2f V_s: %6.2f cita_V_s: %6.2f U_d: %6.2f \n", data_CUR_FREQ[current_counter],data_S_A_f[current_counter]*data_U_d[current_counter],data_S_B_f[current_counter]*data_U_d[current_counter],data_S_C_f[current_counter]*data_U_d[current_counter],data_V_sD[current_counter],data_V_sQ[current_counter],data_V_s[current_counter],data_cita_V_s[current_counter],data_U_d[current_counter]); } else if (print_selection==2) { printf ("t:%5d:f:%6.2f:psi_sD:%9.6f:i_sQ:%6.2f:psi_sQ:%9.6f:i_sD:%6.2f:c_is:%6.2f:psi_an:%6.2f:te:%8.5f:U_d: %5.2f\n", timer[current_counter], data_CUR_FREQ[current_counter], data_psi_sD[current_counter], data_i_sQ[current_counter], data_psi_sQ[current_counter], data_i_sD[current_counter], data_cita_i_s[current_counter], vector_angle(data_psi_sQ[current_counter],data_psi_sD[current_counter]), data_t_e[current_counter], data_U_d[current_counter]); //data_psi_s[current_counter], //data_psi_alpha[current_counter], } else if (print_selection==3) { //printf ("t:%5d:f:%6.2f:r:%6.2f:er:%7.2f:tr:%8.4f:te:%8.4f:dt:%2d:pr:%8.6f:ps:%6.4f:pa:%1d:pn:%6.2f:dp:%2d:v:%3d:c:%6.2f", printf ("t:%5d:f:%6.2f:tr:%8.4f:te:%8.4f:dt:%2d:pr:%8.6f:ps:%6.4f:pa:%1d:pn:%6.2f:dp:%2d:v:%3d:c:%6.2f", timer[current_counter], data_CUR_FREQ[current_counter], data_t_e_ref[current_counter], data_t_e[current_counter], data_d_te[current_counter], data_psi_s_ref[current_counter], data_psi_s[current_counter], data_psi_alpha[current_counter], vector_angle(data_psi_sQ[current_counter],data_psi_sD[current_counter]), data_d_psi[current_counter], data_optimal_voltage_vector[current_counter], data_cita_V_s[current_counter]); //data_S_A[current_counter],data_S_B[current_counter],data_S_C[current_counter], //:SA:%1d:SB:%1d:SC: printf (":iA:%6.2f:B:%6.2f:D:%6.2f:Q:%6.2f:s:%6.2f:c:%6.2f:U:%6.2f", data_i_sA[current_counter],data_i_sB[current_counter],data_i_sD[current_counter],data_i_sQ[current_counter],data_i_s[current_counter],data_cita_i_s[current_counter],data_U_d[current_counter]); printf (":VA:%6.2f:B:%6.2f:C:%6.2f:D:%6.2f:Q: %6.2f:s:%6.2f:c:%6.2f", data_S_A_f[current_counter]*data_U_d[current_counter],data_S_B_f[current_counter]*data_U_d[current_counter],data_S_C_f[current_counter]*data_U_d[current_counter],data_V_sD[current_counter],data_V_sQ[current_counter],data_V_s[current_counter],data_cita_V_s[current_counter]); printf (":pD:%9.6f:pQ:%9.6f\n", data_psi_sD[current_counter], data_psi_sQ[current_counter] ); //data_psi_s[current_counter], //data_psi_alpha[current_counter], } else if (print_selection==4) { while (PID_angle[current_counter]>(2.0f*PI) ) PID_angle[current_counter]=PID_angle[current_counter]-2.0*PI; float ang_PID=(180.0f/PI)*PID_angle[current_counter]; if (ang_PID<0.0f) ang_PID=ang_PID+360.0f; float actual_hall_angle; actual_hall_angle=ang_PID*-1.0f; if (actual_hall_angle<0.0f) actual_hall_angle=actual_hall_angle+360.0f; if (actual_hall_angle>360.0f) actual_hall_angle=actual_hall_angle-360.0f; float diff; diff=actual_hall_angle-vector_angle(data_psi_sQ[current_counter],data_psi_sD[current_counter]); if (diff<0.0f) diff=diff+360.0f; if (actual_hall_angle>360.0f) diff=diff-360.0f; printf ("Vsa: %6.2f isa: %6.2f psisan: %6.2f ha: %8.2f f: %6.2f Ud: %6.2f t: %5d w_r: %9.2f a_h: %6.2f diff: %6.2f\n", data_cita_V_s[current_counter],data_cita_i_s[current_counter], flux_linkage_angle_psi_s_angle(PID_angle[current_counter]), ang_PID,data_CUR_FREQ[current_counter],data_U_d [current_counter],timer[current_counter],data_w_r[current_counter]/(2.0f*PI),actual_hall_angle,diff); } //else if (print_selection==5 )//&& data_V_s[current_counter] > 0.0f) { /* float angle_delay=0.0f; angle_delay=data_cita_i_s[current_counter]-data_cita_V_s[current_counter]; if (angle_delay>=360.0f) angle_delay=angle_delay-360.0f; else if (angle_delay<0.0f) angle_delay=angle_delay+360.0f; printf ("V_sD: %6.2f V_sQ: %6.2f V_s: %6.2f cita_V_s: %6.2f i_sD: %6.2f i_sQ: %6.2f i_s: %6.2f cita_i_s: %6.2f diff: %6.2f\n", data_V_sD[current_counter],data_V_sQ[current_counter],data_V_s[current_counter],data_cita_V_s[current_counter],data_i_sD[current_counter],data_i_sQ[current_counter],data_i_s[current_counter],data_cita_i_s[current_counter],angle_delay); */ /* printf ("V_sD: %6.2f V_sQ: %6.2f i_sD: %6.2f i_sQ: %6.2f psi_sD: %f psi_sQ: %f psi_s: %6.5f psi_alpha: %2d R_s: %6.3f\n", data_V_sD[current_counter],data_V_sQ[current_counter],data_i_sD[current_counter],data_i_sQ[current_counter],data_psi_sD[current_counter],data_psi_sQ[current_counter],data_psi_s[current_counter],data_psi_alpha[current_counter],data_R_s[current_counter]); */ printf (":psi_sD:%9.6f:psi_sQ:%9.6f:psi_s:%6.5f:angle:%6.2f:psi_alpha:%2d:timer:%8d:freq: %6.2f:U_d: %6.2f\n", data_psi_sD[current_counter],data_psi_sQ[current_counter],data_psi_s[current_counter],vector_angle(data_psi_sQ[current_counter],data_psi_sD[current_counter]),data_psi_alpha[current_counter], timer[current_counter], data_CUR_FREQ[current_counter],data_U_d [current_counter]); } /* data_S_A[current_counter]=S_A; data_S_B[current_counter]=S_B; data_S_C[current_counter]=S_C; data_S_A_f[current_counter]=S_A_f; data_S_B_f[current_counter]=S_B_f; data_S_C_f[current_counter]=S_C_f; data_i_sA [current_counter]=i_sA; data_i_sB [current_counter]=i_sB; data_U_d [current_counter]=U_d; data_i_sD[current_counter]=i_sD; data_i_sQ[current_counter]=i_sQ; data_i_s[current_counter]=i_s; data_cita_i_s[current_counter]=cita_i_s; data_V_sD[current_counter]; data_V_sQ[current_counter]; data_V_s [current_counter]; data_cita_V_s[current_counter]; data_psi_sD[current_counter]; data_psi_sQ[current_counter]; data_psi_s [current_counter]; data_psi_alpha[current_counter]; data_t_e[current_counter]; data_psi_s_ref[current_counter]; data_t_e_ref[current_counter]; data_d_psi[current_counter]; data_d_te[current_counter]; data_psi_delta_percentage[current_counter]; data_t_e_delta_percentage[current_counter]; data_R_s[current_counter]; data_pole_pairs[current_counter; data_L_sq[current_counter]; data_psi_F[current_counter]; */ current_counter++; } print_current=false; current_counter=0; } /*2 if (motor_stop==false) { if (print_selection==0) { printf ("freq: %6.2f i_sA: %6.2f i_sB: %6.2f i_sD: %6.2f i_sQ: %6.2f i_s: %6.2f cita_i_s: %6.2f U_d: %6.2f \n", CUR_FREQ,i_sA,i_sB,i_sD,i_sQ,i_s,cita_i_s,U_d); } else if (print_selection==1) { printf ("freq: %6.2f V_sD: %6.2f V_sQ: %6.2f V_s: %6.2f cita_V_s: %6.2f U_d: %6.2f \n", CUR_FREQ,V_sD,V_sQ,V_s,cita_V_s,U_d); } else if (print_selection==2) { printf ("freq: %6.2f psi_sD: %6.2f psi_sQ: %6.2f psi_s: %6.2f psi_alpha: %4d U_d: %6.2f \n", CUR_FREQ,psi_sD,psi_sQ,psi_s,psi_alpha,U_d); } else if (print_selection==3) { printf ("freq: %6.2f t_e: %8.2f psi_s_ref: %6.2f t_e_ref: %6.2f d_psi: %4d d_te: %4d psi_delta: %6.2f t_e_delta: %6.2f \n", CUR_FREQ,t_e,psi_s_ref,t_e_ref,d_psi,d_te,psi_delta_percentage,t_e_delta_percentage); } } */ /* S_A_f S_B_f S_C_f i_sA i_sB U_d i_sD i_sQ i_s cita_i_s V_sD V_sQ V_s cita_V_s psi_sD psi_sQ psi_s psi_alpha t_e psi_s_ref t_e_ref d_psi d_te psi_delta_percentage t_e_delta_percentage //motor parameters; R_s pole_pairs L_sq psi_F */ if(S_A!=2 && S_B!=2 && S_C!=2) { //printf ("freq: %6.2f i_sA: %6.2f i_sB: %6.2f U_d: %6.2f\n", CUR_FREQ,i_sA,i_sB,U_d); } } }
int main(int argc, char *argv[]) { // Initialize randomness srand(time(NULL)); // 7 parameters are required. if (argc != 13) { fprintf(stderr, "Usage: %s obj-file sx sy sz tx ty tz rx ry rz focal-dist hiding\n", argv[0]); return 0; } unsigned int i, j; double sx = atof( argv[2] ); double sy = atof( argv[3] ); double sz = atof( argv[4] ); double tx = atof( argv[5] ); double ty = atof( argv[6] ); double tz = atof( argv[7] ); double rx = atof( argv[8] ); double ry = atof( argv[9] ); double rz = atof( argv[10] ); double fd = atof( argv[11] ); int hiding = atoi( argv[12] ); matrix_double scale = scale_by(sx, sy, sz); matrix_double tras = traslate(tx, ty, tz); matrix_double rot = rotate(rx, ry, rz); matrix_double proj = projection(fd); file_data vnf = readobj(argv[1]); // int p; // for (p = 0; p < vnf.vertices.num_elems; p++) { // point3d t = (vnf.vertices.data)[p]; // fprintf(stderr, "(%f,%f,%f)\n", t.x, t.y, t.z); // } // Join all the transformations in a single matrix // Operation order: Scaling, rotation, traslation and projection matrix_double t1 = product(proj, tras); matrix_double t2 = product(t1, rot); matrix_double t3 = product(t2, scale); apply_matrix(t3, vnf.vertices); dispose_matrix(&t3); dispose_matrix(&t2); dispose_matrix(&t1); dispose_matrix(&scale); dispose_matrix(&tras); dispose_matrix(&rot); dispose_matrix(&proj); // Projection sets w = z, so divide everything by w. for (i = 0; i < vnf.vertices.num_elems; i++) { point3d tmp = (vnf.vertices.data)[i]; tmp.x /= tmp.w; tmp.y /= tmp.w; tmp.z /= tmp.w; (vnf.vertices.data)[i] = tmp; } // The camera normal (taking advantage of perspective projection) vector camera_normal = new_vector( new_point3d(0.0, 0.0, 0.0, 1.0), new_point3d(0.0, 0.0, 1.0, 1.0) ); // The z-buffer double **zbuf = calloc(HEIGHT, sizeof *zbuf); for (i = 0; i < HEIGHT; i++) { zbuf[i] = calloc(WIDTH, sizeof **zbuf); for (j = 0; j < WIDTH; j++) zbuf[i][j] = DBL_MAX; } color c = new_color( 255, 255, 255 ); point center = { WIDTH >> 1, HEIGHT >> 1 }; int invertX = 0, invertY = 1; raster tmp = new_raster(WIDTH, HEIGHT, 3); for (i = 0; i < vnf.faces.num_elems; i++) { point3d v1 = (vnf.vertices.data)[((vnf.faces.data)[i].v1) - 1]; point3d v2 = (vnf.vertices.data)[((vnf.faces.data)[i].v2) - 1]; point3d v3 = (vnf.vertices.data)[((vnf.faces.data)[i].v3) - 1]; point pt[3] = { new_point(v1.x, v1.y), new_point(v2.x, v2.y), new_point(v3.x, v3.y) }; for (j = 0; j < 3; j++) pt[j] = raster_translate(pt[j], center, invertX, invertY); // Hiding faces using face normals if (hiding == 1) { vector va = new_vector( v1, v2 ); vector vb = new_vector( v1, v3 ); vector vn = vector_crossproduct( va, vb ); if ( abs(vector_angle(vn, camera_normal)) < 90.0 ) continue; } // Drawing the face for (j = 0; j < 3; j++) { int curr = j; int next = (j+1) % 3; point ps = pt[curr]; point pe = pt[next]; // Use z-buffering if allowed // if (hiding == 2) // put_line_z(tmp, new_line( ps, pe ), c, bresenham, zbuf, vertices[3][curr], vertices[3][next]); // else put_line(tmp, new_line( ps, pe ), c, bresenham); } // Filling the face using a random, eye-pleasing colour color cr = { ((rand() % 255) + 255) >> 1, ((rand() % 255) + 255) >> 1, ((rand() % 255) + 255) >> 1 }; // if (hiding == 2) // fill_face_z(tmp, pt[0], pt[1], pt[2], cr, zbuf, vertices[3][j], vertices[3][(j+1) % 3]); // elseelse fill_face(tmp, pt[0], pt[1], pt[2], cr); } raster_out(tmp); dispose_raster(tmp); for (i = 0; i < HEIGHT; i++) free(zbuf[i]); free(zbuf); free(vnf.vertices.data); free(vnf.faces.data); return 0; }
static void tick_camera (ModeInfo *mi, camera *c) { camera_configuration *bp = &bps[MI_SCREEN(mi)]; GLfloat X, Y, Z; set_camera_focus (mi, c); X = c->focus.x - c->pos.x; Y = c->focus.y - c->pos.y; Z = c->focus.z - c->pos.z - BEAM_ZOFF; if (X != 0 || Y != 0) { GLfloat ofacing = c->facing; GLfloat opitch = c->pitch; GLfloat target_facing = atan2 (X, Y) * (180 / M_PI); GLfloat target_pitch = atan2 (Z, sqrt(X*X + Y*Y)) * (180 / M_PI); /* Adjust the current velocity. If we are nearing the target, slow down (but don't stop). Otherwise, speed up (but don't break the speed limit). */ { GLfloat accel = 0.5 * speed_arg; GLfloat decel_range = 20; GLfloat max_velocity = 5 * speed_arg; GLfloat close_enough = 0.5 * speed_arg; GLfloat dx = target_facing - c->facing; GLfloat dy = target_pitch - c->pitch; GLfloat angular_distance = sqrt (dx*dx + dy*dy); /* Split the velocity into vx and vy components. This isn't quite right since this treats them as Cartesian rather than polar, but it's close enough. */ GLfloat r = (dx == 0) ? 1 : ABS(dy) / ABS(dx); GLfloat vx = 1-r; GLfloat vy = r; if (angular_distance < decel_range) /* Nearing target, slow down */ { c->velocity -= accel; if (c->velocity <= 0) c->velocity = accel; } else { c->velocity += accel; if (c->velocity > max_velocity) c->velocity = max_velocity; } /* Don't overshoot */ if (vx > ABS(dx)) vx = ABS(dx); if (vy > ABS(dy)) vy = ABS(dy); /* Rotate toward target by current angular velocity. */ c->facing += vx * c->velocity * (target_facing > c->facing ? 1 : -1); c->pitch += vy * c->velocity * (target_pitch > c->pitch ? 1 : -1); /* If we are pointed *really close* to the target, just lock on, to avoid twitchy overshoot rounding errors. */ if (angular_distance < close_enough) { c->facing = target_facing; c->pitch = target_pitch; } /* Constrain to hinge's range of motion */ c->facing = MAX (-90, MIN (90, c->facing)); c->pitch = MAX (-90, MIN (55, c->pitch)); /* After this motion, our prevailing velocity (for next time) is the angular distance we actually moved. */ dx = c->facing - ofacing; dy = c->pitch - opitch; c->velocity = sqrt (dx*dx + dy*dy); } } # ifdef DEBUG if (debug_p && 1) /* Mark the point on which this camera is focusing. */ { glPushMatrix(); glDisable (GL_LIGHTING); glColor3f(0.3, 0.3, 0.3); glBegin (GL_LINES); glVertex3f (c->pos.x, c->pos.y, c->pos.z + BEAM_ZOFF); glVertex3f (c->focus.x, c->focus.y, c->focus.z); glEnd(); glColor3f(1,1,1); glBegin (GL_LINES); glVertex3f (c->focus.x-0.25, c->focus.y, c->focus.z); glVertex3f (c->focus.x+0.25, c->focus.y, c->focus.z); glVertex3f (c->focus.x, c->focus.y-0.25, c->focus.z); glVertex3f (c->focus.x, c->focus.y+0.25, c->focus.z); glVertex3f (c->focus.x, c->focus.y, c->focus.z-0.25); glVertex3f (c->focus.x, c->focus.y, c->focus.z+0.25); glEnd(); if (!MI_IS_WIREFRAME(mi)) glEnable (GL_LIGHTING); glPopMatrix(); } # endif /* If this camera is looking at another camera, get shy and look away if the target sees us looking. */ if (c->focus_id < 0) { camera *c2 = &bp->cameras[-1 - c->focus_id]; XYZ a, b; GLfloat aa = c->facing / (180 / M_PI); GLfloat bb = c->pitch / (180 / M_PI); GLfloat angle; a.y = cos(aa)* cos(bb); a.x = sin(aa)* cos(bb); a.z = sin(bb); aa = c2->facing / (180 / M_PI); bb = c2->pitch / (180 / M_PI); b.y = cos(aa)* cos(bb); b.x = sin(aa)* cos(bb); b.z = sin(bb); angle = vector_angle (normalize(a), normalize(b)) * (180 / M_PI); if (angle > 100) { c->focus_id = 0; /* Look "away" which means in the same direction. */ c->focus.x = c->pos.x + (c2->focus.x - c2->pos.x); c->focus.y = c->pos.y + (c2->focus.y - c2->pos.y); c->focus.z = c->pos.z + (c2->focus.z - c2->pos.z); /* Look at either the sky or the ground.*/ c->focus.z = c->focus.x * (random() & 1 ? 1 : -1) * 5; c->velocity = c2->velocity * 3; } } /* Randomly pick some other things to look at. */ if (c->state == IDLE && (c->focus_id <= 0 ? !(random() % (int) MAX (1, (50 / speed_arg))) : !(random() % (int) MAX (1, (1000 / speed_arg))))) { /* Shiny! Start paying attention to something else. */ if ((bp->ncameras > 1 && !(random() % 20))) /* look at a camera */ { int which = random() % 4; long i; for (i = 0; i < bp->ncameras; i++) if (c == &bp->cameras[i]) break; /* Look at cameras 1 or 2 away in each direction, but not farther. Since we arrange them in 2 staggered lines, those are the only four that are in line of sight. */ if (i >= 2 && which == 0) which = i-2; else if (i >= 1 && which == 1) which = i-1; else if (i < bp->ncameras-1 && which == 2) which = i+2; else /* (i < bp->ncameras-2 && which == 3) */ which = i+1; c->focus_id = -1 - which; } else /* look at a pedestrian */ { int n = 0; pedestrian *p; for (p = bp->pedestrians; p; p = p->next) n++; if (n > 0) { n = random() % n; p = bp->pedestrians; while (n > 0 && p) p = p->next; if (p) c->focus_id = p->id; } } } /* Run the animation */ if (c->state != IDLE) { pedestrian *p = bp->pedestrians; /* first one */ if (p) c->focus_id = p->id; switch (c->state) { case WARM_UP: c->tick -= 0.01 * speed_arg; break; case ZOT: c->tick -= 0.006 * speed_arg; if (p) p->speed *= 0.995; /* target takes 1d6 HP damage */ break; case COOL_DOWN: c->tick -= 0.02 * speed_arg; break; default: abort(); break; } if (c->tick <= 0) { c->tick = 1.0; switch (c->state) { case WARM_UP: c->state = ZOT; break; case ZOT: c->state = COOL_DOWN; c->focus_id = 0; if (p) p->ratio = 1.0; /* threat eliminated */ break; case COOL_DOWN: c->state = IDLE; break; default: abort(); break; } } } if (bp->cameras[0].state == IDLE && bp->pedestrians && bp->pedestrians[0].ratio < 0.3 && !(random() % MAX (1, (int) (50000 / speed_arg)))) { /* CASE NIGHTMARE RED detected, engage SCORPION STARE by authority of MAGINOT BLUE STARS. */ int i; for (i = 0; i < bp->ncameras; i++) { bp->cameras[i].state = WARM_UP; bp->cameras[i].tick = 1.0; } } }
static void build_ball (ModeInfo *mi) { ball_configuration *bp = &bps[MI_SCREEN(mi)]; int rows = MI_COUNT (mi); GLfloat tile_size = M_PI / rows; GLfloat th0, th1; struct { XYZ position; GLfloat strength; } dents[5]; int dent_count = random() % countof(dents); int i; for (i = 0; i < dent_count; i++) { GLfloat dist; dents[i].position.x = RANDSIGN() * (2 - BELLRAND(0.2)); dents[i].position.y = RANDSIGN() * (2 - BELLRAND(0.2)); dents[i].position.z = RANDSIGN() * (2 - BELLRAND(0.2)); dist = sqrt (dents[i].position.x * dents[i].position.x + dents[i].position.y * dents[i].position.y + dents[i].position.z * dents[i].position.z); dents[i].strength = dist - (1 - BELLRAND(0.3)); dents[i].strength = dist - (1 - BELLRAND(0.3)); } for (th1 = M_PI/2; th1 > -(M_PI/2 + tile_size/2); th1 -= tile_size) { GLfloat x = cos (th1); GLfloat y = sin (th1); GLfloat x0 = cos (th1 - tile_size/2); GLfloat x1 = cos (th1 + tile_size/2); GLfloat circ0 = M_PI * x0 * 2; GLfloat circ1 = M_PI * x1 * 2; GLfloat circ = (circ0 < circ1 ? circ0 : circ1); int row_tiles = floor ((circ < 0 ? 0 : circ) / tile_size); GLfloat spacing; GLfloat dropsy = 0.13 + frand(0.04); if (row_tiles <= 0) row_tiles = 1; spacing = M_PI*2 / row_tiles; for (th0 = 0; th0 < M_PI*2; th0 += spacing) { tile *t = (tile *) calloc (1, sizeof(*t)); t->size = tile_size * 0.85; t->position.x = cos (th0) * x; t->position.y = sin (th0) * x; t->position.z = y; t->normal = t->position; /* Apply pressure on position from the dents. */ for (i = 0; i < dent_count; i++) { GLfloat dist; XYZ direction; if (! (random() % 150)) /* Drop tiles randomly */ { free (t); goto SKIP; } direction.x = t->position.x - dents[i].position.x; direction.y = t->position.y - dents[i].position.y; direction.z = t->position.z - dents[i].position.z; dist = sqrt (direction.x * direction.x + direction.y * direction.y + direction.z * direction.z); if (dist < dents[i].strength) { GLfloat s = 1 - (dents[i].strength - dist) * 0.66; XYZ n2 = t->normal; GLfloat angle = vector_angle (t->position, dents[i].position); /* Drop out the tiles near the apex of the dent. */ if (angle < dropsy) { free (t); goto SKIP; } t->position.x *= s; t->position.y *= s; t->position.z *= s; direction = normalize (direction); n2.x -= direction.x; n2.y -= direction.y; n2.z -= direction.z; t->normal.x = (t->normal.x + n2.x) / 2; t->normal.y = (t->normal.y + n2.y) / 2; t->normal.z = (t->normal.z + n2.z) / 2; } } /* Skew the direction the tile is facing slightly. */ t->normal.x += 0.12 - frand(0.06); t->normal.y += 0.12 - frand(0.06); t->normal.z += 0.12 - frand(0.06); t->tilt = 4 - BELLRAND(8); t->next = bp->tiles; bp->tiles = t; SKIP: ; } } bp->nrays = 5 + BELLRAND(10); bp->rays = (ray *) calloc (bp->nrays, sizeof(*bp->rays)); for (i = 0; i < bp->nrays; i++) { GLfloat th = frand(M_PI * 2); bp->rays[i].normal.x = cos (th); bp->rays[i].normal.y = sin (th); bp->rays[i].normal.z = 1; bp->rays[i].normal = normalize (bp->rays[i].normal); bp->rays[i].color[0] = 0.9 + frand(0.1); bp->rays[i].color[1] = 0.6 + frand(0.4); bp->rays[i].color[2] = 0.6 + frand(0.2); bp->rays[i].color[3] = 1; } }
static void make_gasket (logo_configuration *dc, int wire) { int i; int points_size; int npoints = 0; int nctrls = 0; int res = 360/8; GLfloat d2r = M_PI / 180; GLfloat thick2 = (dc->gasket_thickness / dc->gasket_size) / 2; GLfloat *pointsx0, *pointsy0, *pointsx1, *pointsy1, *normals; GLfloat r0 = 0.780; /* 395 */ GLfloat r1a = 0.855; /* top of wall below upper left hole */ GLfloat r1b = 0.890; /* center of upper left hole */ GLfloat r1c = 0.922; /* bottom of wall above hole */ GLfloat r1 = 0.928; /* 471 */ GLfloat r2 = 0.966; /* 490 */ GLfloat r3 = 0.984; /* 499 */ GLfloat r4 = 1.000; /* 507 */ GLfloat r5 = 1.090; /* 553 */ GLfloat ctrl_r[100], ctrl_th[100]; glPushMatrix(); # define POINT(r,th) \ ctrl_r [nctrls] = r, \ ctrl_th[nctrls] = (th * d2r), \ nctrls++ POINT (0.829, 0); /* top indentation, right half */ POINT (0.831, 0.85); POINT (0.835, 1.81); POINT (0.841, 2.65); POINT (0.851, 3.30); POINT (0.862, 3.81); POINT (0.872, 3.95); POINT (r4, 4.0); /* moving clockwise... */ POINT (r4, 48.2); POINT (r1, 48.2); POINT (r1, 54.2); POINT (r2, 55.8); POINT (r2, 73.2); POINT (r1, 74.8); POINT (r1, 101.2); POINT (r3, 103.4); POINT (r3, 132.0); POINT (r1, 133.4); POINT (r1, 180.7); POINT (r2, 183.6); POINT (r2, 209.8); POINT (r1, 211.0); POINT (r1, 221.8); POINT (r5, 221.8); POINT (r5, 223.2); POINT (r4, 223.2); POINT (r4, 316.8); /* upper left indentation */ POINT (0.990, 326.87); POINT (0.880, 327.21); POINT (0.872, 327.45); POINT (0.869, 327.80); POINT (0.867, 328.10); POINT (0.867, 328.85); POINT (0.869, 329.15); POINT (0.872, 329.50); POINT (0.880, 329.74); POINT (0.990, 330.08); POINT (r4, 339.0); if (! wire) { POINT (r1a, 339.0); /* cut-out disc */ POINT (r1a, 343.0); } POINT (r4, 343.0); POINT (r4, 356.0); POINT (0.872, 356.05); /* top indentation, left half */ POINT (0.862, 356.19); POINT (0.851, 356.70); POINT (0.841, 357.35); POINT (0.835, 358.19); POINT (0.831, 359.15); POINT (0.829, 360); # undef POINT points_size = res + (nctrls * 2); pointsx0 = (GLfloat *) malloc (points_size * sizeof(GLfloat)); pointsy0 = (GLfloat *) malloc (points_size * sizeof(GLfloat)); pointsx1 = (GLfloat *) malloc (points_size * sizeof(GLfloat)); pointsy1 = (GLfloat *) malloc (points_size * sizeof(GLfloat)); normals = (GLfloat *) malloc (points_size * sizeof(GLfloat) * 2); npoints = 0; for (i = 1; i < nctrls; i++) { GLfloat from_r = ctrl_r [i-1]; GLfloat from_th = ctrl_th[i-1]; GLfloat to_r = ctrl_r [i]; GLfloat to_th = ctrl_th[i]; GLfloat step = 2*M_PI / res; int nsteps = 1 + ((to_th - from_th) / step); int j; for (j = 0; j < nsteps + (i == nctrls-1); j++) { GLfloat r = from_r + (j * (to_r - from_r) / nsteps); GLfloat th = from_th + (j * (to_th - from_th) / nsteps); GLfloat cth = cos(th) * dc->gasket_size; GLfloat sth = sin(th) * dc->gasket_size; pointsx0[npoints] = r0 * cth; /* inner ring */ pointsy0[npoints] = r0 * sth; pointsx1[npoints] = r * cth; /* outer ring */ pointsy1[npoints] = r * sth; npoints++; if (npoints >= points_size) abort(); } } /* normals for the outer ring */ for (i = 1; i < npoints; i++) { XYZ a, b, c, n; a.x = pointsx1[i-1]; a.y = pointsy1[i-1]; a.z = 0; b.x = pointsx1[i]; b.y = pointsy1[i]; b.z = 0; c = b; c.z = 1; n = calc_normal (a, b, c); normals[(i-1)*2 ] = n.x; normals[(i-1)*2+1] = n.y; } glRotatef(-90, 0, 1, 0); glRotatef(180, 0, 0, 1); if (wire) { GLfloat z; for (z = -thick2; z <= thick2; z += thick2*2) { # if 1 /* inside edge */ glBegin (GL_LINE_LOOP); for (i = 0; i < npoints; i++) glVertex3f (pointsx0[i], pointsy0[i], z); glEnd(); /* outside edge */ glBegin (GL_LINE_LOOP); for (i = 0; i < npoints; i++) glVertex3f (pointsx1[i], pointsy1[i], z); glEnd(); # else for (i = 1; i < npoints; i++) { glBegin (GL_LINE_STRIP); glVertex3f (pointsx0[i-1], pointsy0[i-1], z); glVertex3f (pointsx0[i ], pointsy0[i ], z); glVertex3f (pointsx1[i ], pointsy1[i ], z); glVertex3f (pointsx1[i-1], pointsy1[i-1], z); glEnd(); } # endif } #if 1 glBegin (GL_LINES); for (i = 0; i < npoints; i++) { /* inside rim */ glVertex3f (pointsx0[i], pointsy0[i], -thick2); glVertex3f (pointsx0[i], pointsy0[i], thick2); /* outside rim */ glVertex3f (pointsx1[i], pointsy1[i], -thick2); glVertex3f (pointsx1[i], pointsy1[i], thick2); } glEnd(); #endif } else { /* top */ glFrontFace(GL_CW); glNormal3f(0, 0, -1); glBegin (GL_QUAD_STRIP); for (i = 0; i < npoints; i++) { glVertex3f (pointsx0[i], pointsy0[i], -thick2); glVertex3f (pointsx1[i], pointsy1[i], -thick2); } glEnd(); /* bottom */ glFrontFace(GL_CCW); glNormal3f(0, 0, 1); glBegin (GL_QUAD_STRIP); for (i = 0; i < npoints; i++) { glVertex3f (pointsx0[i], pointsy0[i], thick2); glVertex3f (pointsx1[i], pointsy1[i], thick2); } glEnd(); /* inside edge */ glFrontFace(GL_CW); glBegin (GL_QUAD_STRIP); for (i = 0; i < npoints; i++) { glNormal3f (-pointsx0[i], -pointsy0[i], 0); glVertex3f ( pointsx0[i], pointsy0[i], thick2); glVertex3f ( pointsx0[i], pointsy0[i], -thick2); } glEnd(); /* outside edge */ glFrontFace(GL_CCW); glBegin (GL_QUADS); { for (i = 0; i < npoints-1; i++) { int ia = (i == 0 ? npoints-2 : i-1); int iz = (i == npoints-2 ? 0 : i+1); GLfloat x = pointsx1[i]; GLfloat y = pointsy1[i]; GLfloat xz = pointsx1[iz]; GLfloat yz = pointsy1[iz]; GLfloat nxa = normals[ia*2]; /* normal of [i-1 - i] face */ GLfloat nya = normals[ia*2+1]; GLfloat nx = normals[i*2]; /* normal of [i - i+1] face */ GLfloat ny = normals[i*2+1]; GLfloat nxz = normals[iz*2]; /* normal of [i+1 - i+2] face */ GLfloat nyz = normals[iz*2+1]; GLfloat anglea = vector_angle (nx, ny, 0, nxa, nya, 0); GLfloat anglez = vector_angle (nx, ny, 0, nxz, nyz, 0); GLfloat pointy = 0.005; if (anglea > pointy) { glNormal3f (nx, ny, 0); glVertex3f (x, y, thick2); glVertex3f (x, y, -thick2); } else { glNormal3f ((nxa + nx) / 2, (nya + ny) / 2, 0); glVertex3f (x, y, thick2); glVertex3f (x, y, -thick2); } if (anglez > pointy) { glNormal3f (nx, ny, 0); glVertex3f (xz, yz, -thick2); glVertex3f (xz, yz, thick2); } else { glNormal3f ((nx + nxz) / 2, (ny + nyz) / 2, 0); glVertex3f (xz, yz, -thick2); glVertex3f (xz, yz, thick2); } } } glEnd(); } /* Fill in the upper left hole... */ { GLfloat th; npoints = 0; th = 339.0 * d2r; pointsx0[npoints] = r1c * cos(th) * dc->gasket_size; pointsy0[npoints] = r1c * sin(th) * dc->gasket_size; npoints++; pointsx0[npoints] = r4 * cos(th) * dc->gasket_size; pointsy0[npoints] = r4 * sin(th) * dc->gasket_size; npoints++; th = 343.0 * d2r; pointsx0[npoints] = r1c * cos(th) * dc->gasket_size; pointsy0[npoints] = r1c * sin(th) * dc->gasket_size; npoints++; pointsx0[npoints] = r4 * cos(th) * dc->gasket_size; pointsy0[npoints] = r4 * sin(th) * dc->gasket_size; npoints++; if (! wire) { /* front wall */ glNormal3f (0, 0, -1); glFrontFace(GL_CW); glBegin (wire ? GL_LINE_LOOP : GL_QUADS); glVertex3f (pointsx0[0], pointsy0[0], -thick2); glVertex3f (pointsx0[1], pointsy0[1], -thick2); glVertex3f (pointsx0[3], pointsy0[3], -thick2); glVertex3f (pointsx0[2], pointsy0[2], -thick2); glEnd(); /* back wall */ glNormal3f (0, 0, 1); glFrontFace(GL_CCW); glBegin (wire ? GL_LINE_LOOP : GL_QUADS); glVertex3f (pointsx0[0], pointsy0[0], thick2); glVertex3f (pointsx0[1], pointsy0[1], thick2); glVertex3f (pointsx0[3], pointsy0[3], thick2); glVertex3f (pointsx0[2], pointsy0[2], thick2); glEnd(); } /* top wall */ glFrontFace(GL_CW); glBegin (wire ? GL_LINE_LOOP : GL_QUADS); glNormal3f (pointsx0[1], pointsy0[1], 0); glVertex3f (pointsx0[1], pointsy0[1], thick2); glNormal3f (pointsx0[3], pointsy0[3], 0); glVertex3f (pointsx0[3], pointsy0[3], thick2); glVertex3f (pointsx0[3], pointsy0[3], -thick2); glNormal3f (pointsx0[1], pointsy0[1], 0); glVertex3f (pointsx0[1], pointsy0[1], -thick2); glEnd(); /* Now make a donut. */ { int nsteps = 12; GLfloat r0 = 0.026; GLfloat r1 = 0.060; GLfloat th, cth, sth; glPushMatrix (); th = ((339.0 + 343.0) / 2) * d2r; glTranslatef (r1b * cos(th) * dc->gasket_size, r1b * sin(th) * dc->gasket_size, 0); npoints = 0; for (i = 0; i < nsteps; i++) { th = 2 * M_PI * i / nsteps; cth = cos (th) * dc->gasket_size; sth = sin (th) * dc->gasket_size; pointsx0[npoints] = r0 * cth; pointsy0[npoints] = r0 * sth; pointsx1[npoints] = r1 * cth; pointsy1[npoints] = r1 * sth; npoints++; } pointsx0[npoints] = pointsx0[0]; pointsy0[npoints] = pointsy0[0]; pointsx1[npoints] = pointsx1[0]; pointsy1[npoints] = pointsy1[0]; npoints++; if (wire) { glBegin (GL_LINE_LOOP); for (i = 0; i < npoints; i++) glVertex3f (pointsx0[i], pointsy0[i], -thick2); glEnd(); glBegin (GL_LINE_LOOP); for (i = 0; i < npoints; i++) glVertex3f (pointsx0[i], pointsy0[i], thick2); glEnd(); # if 0 glBegin (GL_LINE_LOOP); for (i = 0; i < npoints; i++) glVertex3f (pointsx1[i], pointsy1[i], -thick2); glEnd(); glBegin (GL_LINE_LOOP); for (i = 0; i < npoints; i++) glVertex3f (pointsx1[i], pointsy1[i], thick2); glEnd(); # endif } else { /* top */ glFrontFace(GL_CW); glNormal3f(0, 0, -1); glBegin (GL_QUAD_STRIP); for (i = 0; i < npoints; i++) { glVertex3f (pointsx0[i], pointsy0[i], -thick2); glVertex3f (pointsx1[i], pointsy1[i], -thick2); } glEnd(); /* bottom */ glFrontFace(GL_CCW); glNormal3f(0, 0, 1); glBegin (GL_QUAD_STRIP); for (i = 0; i < npoints; i++) { glVertex3f (pointsx0[i], pointsy0[i], thick2); glVertex3f (pointsx1[i], pointsy1[i], thick2); } glEnd(); } /* inside edge */ glFrontFace(GL_CW); glBegin (wire ? GL_LINES : GL_QUAD_STRIP); for (i = 0; i < npoints; i++) { glNormal3f (-pointsx0[i], -pointsy0[i], 0); glVertex3f ( pointsx0[i], pointsy0[i], thick2); glVertex3f ( pointsx0[i], pointsy0[i], -thick2); } glEnd(); glPopMatrix(); } } /* Attach the bottom-right dingus... */ { GLfloat w = 0.04; GLfloat h = 0.17; GLfloat th; glRotatef (50, 0, 0, 1); glScalef (dc->gasket_size, dc->gasket_size, 1); glTranslatef (0, (r0+r1)/2, 0); /* buried box */ if (! wire) { glFrontFace(GL_CCW); glBegin (wire ? GL_LINE_STRIP : GL_QUADS); glNormal3f (0, 0, -1); glVertex3f (-w/2, -h/2, -thick2); glVertex3f (-w/2, h/2, -thick2); glVertex3f ( w/2, h/2, -thick2); glVertex3f ( w/2, -h/2, -thick2); glNormal3f (1, 0, 0); glVertex3f ( w/2, -h/2, -thick2); glVertex3f ( w/2, h/2, -thick2); glVertex3f ( w/2, h/2, thick2); glVertex3f ( w/2, -h/2, thick2); glNormal3f (0, 0, 1); glVertex3f ( w/2, -h/2, thick2); glVertex3f ( w/2, h/2, thick2); glVertex3f (-w/2, h/2, thick2); glVertex3f (-w/2, -h/2, thick2); glNormal3f (-1, 0, 0); glVertex3f (-w/2, -h/2, thick2); glVertex3f (-w/2, h/2, thick2); glVertex3f (-w/2, h/2, -thick2); glVertex3f (-w/2, -h/2, -thick2); glEnd(); } npoints = 0; for (th = 0; th < M_PI; th += (M_PI / 6)) { pointsx0[npoints] = w/2 * cos(th); pointsy0[npoints] = w/2 * sin(th); npoints++; } /* front inside curve */ glNormal3f (0, 0, -1); glFrontFace(GL_CW); glBegin (wire ? GL_LINE_STRIP : GL_TRIANGLE_FAN); if (! wire) glVertex3f (0, h/2, -thick2); for (i = 0; i < npoints; i++) glVertex3f (pointsx0[i], h/2 + pointsy0[i], -thick2); glEnd(); /* front outside curve */ glFrontFace(GL_CCW); glBegin (wire ? GL_LINE_STRIP : GL_TRIANGLE_FAN); if (! wire) glVertex3f (0, -h/2, -thick2); for (i = 0; i < npoints; i++) glVertex3f (pointsx0[i], -h/2 - pointsy0[i], -thick2); glEnd(); /* back inside curve */ glNormal3f (0, 0, 1); glFrontFace(GL_CCW); glBegin (wire ? GL_LINE_STRIP : GL_TRIANGLE_FAN); if (! wire) glVertex3f (0, h/2, thick2); for (i = 0; i < npoints; i++) glVertex3f (pointsx0[i], h/2 + pointsy0[i], thick2); glEnd(); /* back outside curve */ glFrontFace(GL_CW); glBegin (wire ? GL_LINE_STRIP : GL_TRIANGLE_FAN); if (! wire) glVertex3f (0, -h/2, thick2); for (i = 0; i < npoints; i++) glVertex3f (pointsx0[i], -h/2 - pointsy0[i], thick2); glEnd(); /* inside curve */ glFrontFace(GL_CCW); glBegin (wire ? GL_LINES : GL_QUAD_STRIP); for (i = 0; i < npoints; i++) { glNormal3f (pointsx0[i], pointsy0[i], 0); glVertex3f (pointsx0[i], h/2 + pointsy0[i], thick2); glVertex3f (pointsx0[i], h/2 + pointsy0[i], -thick2); } glEnd(); /* outside curve */ glFrontFace(GL_CW); glBegin (wire ? GL_LINES : GL_QUAD_STRIP); for (i = 0; i < npoints; i++) { glNormal3f (pointsx0[i], -pointsy0[i], 0); glVertex3f (pointsx0[i], -h/2 - pointsy0[i], thick2); glVertex3f (pointsx0[i], -h/2 - pointsy0[i], -thick2); } glEnd(); } free (pointsx0); free (pointsy0); free (pointsx1); free (pointsy1); free (normals); glPopMatrix(); }