struct maybe_point sphere_intersection_point(struct ray r, struct sphere s){ struct maybe_point p; double A = dot_vector(r.dir,r.dir); double B = 2 * dot_vector(difference_point(r.p,s.center), r.dir); double C = dot_vector(difference_point(r.p,s.center), difference_point(r.p, s.center)) - s.radius*s.radius; double E = (-B+sqrt(B*B-4*A*C))/2/A; double F = (-B-sqrt(B*B-4*A*C))/2/A; if((E>0&& F>0)){ p.isPoint = 1; if(E>F) p.p = translate_point(r.p, scale_vector(r.dir,F)); else p.p = translate_point(r.p, scale_vector(r.dir,E)); }else if((E>0||F>0)){ p.isPoint = 1; if(E>0) p.p = translate_point(r.p, scale_vector(r.dir,E)); else p.p = translate_point(r.p, scale_vector(r.dir,F)); }else{ p.isPoint =0; p.p = create_point(0,0,0); } return p; }
void Grenade::damage_blocks(int multiplier) { #if DC_SERVER const TerrainModificationAction action = TMA_GRENADE; const int ir = GRENADE_BLOCK_DESTROY_RADIUS; Vec3 position = this->get_position(); int mx = position.x; int my = position.y; int mz = position.z; for (int i=mx-ir; i<mx+ir; i++) for (int j=my-ir; j<my+ir; j++) for (int k=mz-ir; k<mz+ir; k++) { if (k <= 0 || k >= map_dim.z) continue; int x = translate_point(i); int y = translate_point(j); int z = k; int dmg = this->block_damage(abs(x-mx)+abs(y-my)+abs(z-mz)); if (dmg <= 0) continue; t_map::apply_damage_broadcast(x,y,z, dmg*multiplier, action); } #endif }
struct maybe_point sphere_intersection_point(struct ray r, struct sphere s) { double a = dot_vector(r.dir, r.dir); double b = 2 * dot_vector(difference_point(r.p, s.center), r.dir); double c = dot_vector(difference_point(r.p, s.center), difference_point(r.p, s.center)) - (s.radius * s.radius); double disc = discriminant(a, b, c); double pos_result = pos_quadratic(a, b, c); double neg_result = neg_quadratic(a, b, c); double result; if (disc < 0) { return create_maybe_point(0, create_point(0.0, 0.0, 0.0)); } if (pos_result > 0 && neg_result > 0) { if (pos_result < neg_result) { result = pos_result; } else { result = neg_result; } } else if (pos_result > 0) { result = pos_result; } else if (neg_result > 0) { result = neg_result; } else { result = -1; } if (result > 0) { /*point is valid*/ return create_maybe_point(1, translate_point(r.p, scale_vector(r.dir, result))); } else { /* point is invalid*/ return create_maybe_point(0, translate_point(r.p, scale_vector(r.dir, result))); } }
/* * Construct a fan around the midpoint using the vertices from pen between * inpt and outpt. */ static void add_fan (struct stroker *stroker, const cairo_slope_t *in_vector, const cairo_slope_t *out_vector, const cairo_point_t *midpt, cairo_bool_t clockwise, struct stroke_contour *c) { cairo_pen_t *pen = &stroker->pen; int start, stop; if (stroker->has_bounds && ! _cairo_box_contains_point (&stroker->bounds, midpt)) return; assert (stroker->pen.num_vertices); if (clockwise) { _cairo_pen_find_active_cw_vertices (pen, in_vector, out_vector, &start, &stop); while (start != stop) { cairo_point_t p = *midpt; translate_point (&p, &pen->vertices[start].point); contour_add_point (stroker, c, &p); if (++start == pen->num_vertices) start = 0; } } else { _cairo_pen_find_active_ccw_vertices (pen, in_vector, out_vector, &start, &stop); while (start != stop) { cairo_point_t p = *midpt; translate_point (&p, &pen->vertices[start].point); contour_add_point (stroker, c, &p); if (start-- == 0) start += pen->num_vertices; } } }
static void compute_face (const cairo_point_t *point, const cairo_slope_t *dev_slope, struct stroker *stroker, cairo_stroke_face_t *face) { double face_dx, face_dy; cairo_point_t offset_ccw, offset_cw; double slope_dx, slope_dy; slope_dx = _cairo_fixed_to_double (dev_slope->dx); slope_dy = _cairo_fixed_to_double (dev_slope->dy); face->length = normalize_slope (&slope_dx, &slope_dy); face->dev_slope.x = slope_dx; face->dev_slope.y = slope_dy; /* * rotate to get a line_width/2 vector along the face, note that * the vector must be rotated the right direction in device space, * but by 90° in user space. So, the rotation depends on * whether the ctm reflects or not, and that can be determined * by looking at the determinant of the matrix. */ if (! _cairo_matrix_is_identity (stroker->ctm_inverse)) { /* Normalize the matrix! */ cairo_matrix_transform_distance (stroker->ctm_inverse, &slope_dx, &slope_dy); normalize_slope (&slope_dx, &slope_dy); if (stroker->ctm_det_positive) { face_dx = - slope_dy * (stroker->style.line_width / 2.0); face_dy = slope_dx * (stroker->style.line_width / 2.0); } else { face_dx = slope_dy * (stroker->style.line_width / 2.0); face_dy = - slope_dx * (stroker->style.line_width / 2.0); } /* back to device space */ cairo_matrix_transform_distance (stroker->ctm, &face_dx, &face_dy); } else { face_dx = - slope_dy * (stroker->style.line_width / 2.0); face_dy = slope_dx * (stroker->style.line_width / 2.0); } offset_ccw.x = _cairo_fixed_from_double (face_dx); offset_ccw.y = _cairo_fixed_from_double (face_dy); offset_cw.x = -offset_ccw.x; offset_cw.y = -offset_ccw.y; face->ccw = *point; translate_point (&face->ccw, &offset_ccw); face->point = *point; face->cw = *point; translate_point (&face->cw, &offset_cw); face->usr_vector.x = slope_dx; face->usr_vector.y = slope_dy; face->dev_vector = *dev_slope; }
/* * Construct a fan around the midpoint using the vertices from pen between * inpt and outpt. */ static void add_fan (struct stroker *stroker, const cairo_slope_t *in_vector, const cairo_slope_t *out_vector, const cairo_point_t *midpt, const cairo_point_t *inpt, const cairo_point_t *outpt, cairo_bool_t clockwise) { int start, stop, step, i, npoints; if (clockwise) { step = 1; start = _cairo_pen_find_active_cw_vertex_index (&stroker->pen, in_vector); if (_cairo_slope_compare (&stroker->pen.vertices[start].slope_cw, in_vector) < 0) start = range_step (start, 1, stroker->pen.num_vertices); stop = _cairo_pen_find_active_cw_vertex_index (&stroker->pen, out_vector); if (_cairo_slope_compare (&stroker->pen.vertices[stop].slope_ccw, out_vector) > 0) { stop = range_step (stop, -1, stroker->pen.num_vertices); if (_cairo_slope_compare (&stroker->pen.vertices[stop].slope_cw, in_vector) < 0) return; } npoints = stop - start; } else { step = -1; start = _cairo_pen_find_active_ccw_vertex_index (&stroker->pen, in_vector); if (_cairo_slope_compare (&stroker->pen.vertices[start].slope_ccw, in_vector) < 0) start = range_step (start, -1, stroker->pen.num_vertices); stop = _cairo_pen_find_active_ccw_vertex_index (&stroker->pen, out_vector); if (_cairo_slope_compare (&stroker->pen.vertices[stop].slope_cw, out_vector) > 0) { stop = range_step (stop, 1, stroker->pen.num_vertices); if (_cairo_slope_compare (&stroker->pen.vertices[stop].slope_ccw, in_vector) < 0) return; } npoints = start - stop; } stop = range_step (stop, step, stroker->pen.num_vertices); if (npoints < 0) npoints += stroker->pen.num_vertices; if (npoints <= 1) return; for (i = start; i != stop; i = range_step (i, step, stroker->pen.num_vertices)) { cairo_point_t p = *midpt; translate_point (&p, &stroker->pen.vertices[i].point); //contour_add_point (stroker, c, &p); } }
struct maybe_point sphere_intersection_point(struct ray r, struct sphere s) { double a = dot_vector(r.dir,r.dir); struct vector v=difference_point(r.p,s.center); double b = 2*dot_vector(v,r.dir); double c = dot_vector(v,v) - (s.radius*s.radius); if( (b*b-4*a*c)>0) //two real roots { double t1 = ( (-b+sqrt((b*b)-(4*a*c)))/(2*a)); double t2 = ( (-b-sqrt((b*b)-(4*a*c)))/(2*a)); if(t1>0 && t2>0) // ray hits sphere twice, need lower t value { if(t1<=t2) { struct maybe_point mp5; mp5.isPoint=1; mp5.p=translate_point(r.p,scale_vector(r.dir,t1)); return mp5; } else { struct maybe_point mp6; mp6.isPoint=1; mp6.p=translate_point(r.p,scale_vector(r.dir,t2)); return mp6; } } else if( (t1>0&&t2<0) || (t1<0&&t2>0) ) //t is positive and negative,need positive t value { if(t1>0) { struct maybe_point mp7; mp7.isPoint=1; mp7.p=translate_point(r.p,scale_vector(r.dir,t1)); return mp7; } else { struct maybe_point mp8; mp8.isPoint=1; mp8.p=translate_point(r.p,scale_vector(r.dir,t2)); return mp8; } } else //no intersection, both t's negative { struct maybe_point mp1; mp1.isPoint=0; mp1.p.x=0; mp1.p.y=0; mp1.p.z=0; return mp1; } } else if( (b*b-4*a*c)==0)//one real root { printf("oneroot!"); double t3 = -b/2*a; if(t3>0)//t is positive, so the ray intersects sphere tangentially { struct maybe_point mp2; mp2.isPoint=1; mp2.p=translate_point(r.p,scale_vector(r.dir,t3)); return mp2; } else //t is negative, so ray does not intersect sphere. //also includes the case where t==0, where the ray starting //point is on the sphere. am going to treat like non-intersection { struct maybe_point mp3; mp3.isPoint=0; mp3.p.x=0; mp3.p.y=0; mp3.p.z=0; return mp3; } } else // no real roots { struct maybe_point mp; mp.isPoint=0; mp.p.x=0; mp.p.y=0; mp.p.z=0; return mp; } }
Point translate_point_copy(const Point & point, const Vector3 & vec) { Point ret(point); translate_point(ret, vec); return ret; }
/* * \brief Convert token list to outline. Calls the line and curve evaluators. */ FT_Outline *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode) { int started = 0; ASS_DrawingToken *token; FT_Vector pen = {0, 0}; drawing->tokens = drawing_tokenize(drawing->text); drawing_prepare(drawing); token = drawing->tokens; while (token) { // Draw something according to current command switch (token->type) { case TOKEN_MOVE_NC: pen = token->point; translate_point(drawing, &pen); token = token->next; break; case TOKEN_MOVE: pen = token->point; translate_point(drawing, &pen); if (started) { drawing_close_shape(drawing); started = 0; } token = token->next; break; case TOKEN_LINE: { FT_Vector to; to = token->point; translate_point(drawing, &to); if (!started) drawing_add_point(drawing, &pen); drawing_add_point(drawing, &to); started = 1; token = token->next; break; } case TOKEN_CUBIC_BEZIER: if (token_check_values(token, 3, TOKEN_CUBIC_BEZIER) && token->prev) { drawing_evaluate_curve(drawing, token->prev, 0, started); token = token->next; token = token->next; token = token->next; started = 1; } else token = token->next; break; case TOKEN_B_SPLINE: if (token_check_values(token, 3, TOKEN_B_SPLINE) && token->prev) { drawing_evaluate_curve(drawing, token->prev, 1, started); token = token->next; started = 1; } else token = token->next; break; default: token = token->next; break; } } drawing_finish(drawing, raw_mode); drawing_free_tokens(drawing->tokens); return &drawing->outline; }
/* * \brief Evaluate a curve into lines * This curve evaluator is also used in VSFilter (RTS.cpp); it's a simple * implementation of the De Casteljau algorithm. */ static void drawing_evaluate_curve(ASS_Drawing *drawing, ASS_DrawingToken *token, char spline, int started) { double cx3, cx2, cx1, cx0, cy3, cy2, cy1, cy0; double t, h, max_accel, max_accel1, max_accel2; FT_Vector cur = {0, 0}; cur = token->point; translate_point(drawing, &cur); int x0 = cur.x; int y0 = cur.y; token = token->next; cur = token->point; translate_point(drawing, &cur); int x1 = cur.x; int y1 = cur.y; token = token->next; cur = token->point; translate_point(drawing, &cur); int x2 = cur.x; int y2 = cur.y; token = token->next; cur = token->point; translate_point(drawing, &cur); int x3 = cur.x; int y3 = cur.y; if (spline) { // 1 [-1 +3 -3 +1] // - * [+3 -6 +3 0] // 6 [-3 0 +3 0] // [+1 +4 +1 0] double div6 = 1.0/6.0; cx3 = div6*(- x0+3*x1-3*x2+x3); cx2 = div6*( 3*x0-6*x1+3*x2); cx1 = div6*(-3*x0 +3*x2); cx0 = div6*( x0+4*x1+1*x2); cy3 = div6*(- y0+3*y1-3*y2+y3); cy2 = div6*( 3*y0-6*y1+3*y2); cy1 = div6*(-3*y0 +3*y2); cy0 = div6*( y0+4*y1+1*y2); } else { // [-1 +3 -3 +1] // [+3 -6 +3 0] // [-3 +3 0 0] // [+1 0 0 0] cx3 = - x0+3*x1-3*x2+x3; cx2 = 3*x0-6*x1+3*x2; cx1 = -3*x0+3*x1; cx0 = x0; cy3 = - y0+3*y1-3*y2+y3; cy2 = 3*y0-6*y1+3*y2; cy1 = -3*y0+3*y1; cy0 = y0; } max_accel1 = fabs(2 * cy2) + fabs(6 * cy3); max_accel2 = fabs(2 * cx2) + fabs(6 * cx3); max_accel = FFMAX(max_accel1, max_accel2); h = 1.0; if (max_accel > CURVE_ACCURACY) h = sqrt(CURVE_ACCURACY / max_accel); if (!started) { cur.x = cx0; cur.y = cy0; drawing_add_point(drawing, &cur); } for (t = 0; t < 1.0; t += h) { cur.x = cx0 + t * (cx1 + t * (cx2 + t * cx3)); cur.y = cy0 + t * (cy1 + t * (cy2 + t * cy3)); drawing_add_point(drawing, &cur); } cur.x = cx0 + cx1 + cx2 + cx3; cur.y = cy0 + cy1 + cy2 + cy3; drawing_add_point(drawing, &cur); }