Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- pair<ld, Vec3d> dist_to_arena_quarter(Vec3d point, const Arena& arena){
- //ground
- pair<ld, Vec3d> dist = dist_to_plane(point, Vec3d(0,0,0), Vec3d(0, 1, 0));
- //ceil
- dist = min(dist, dist_to_plane(point, Vec3d(0, arena.height, 0), Vec3d(0, -1, 0)));
- //side x
- dist = min(dist, dist_to_plane(point, Vec3d(arena.width/2, 0, 0), Vec3d(-1, 0, 0)));
- //side z(goal)
- dist = min(dist, dist_to_plane(point, Vec3d(0,0, arena.depth / 2 + arena.goal_depth), Vec3d(0,0,-1)));
- //side z
- Vec3d v = Vec3d(point.x, point.y, 0) - Vec3d(arena.goal_width / 2 - arena.goal_top_radius, arena.goal_height - arena.goal_top_radius, 0);
- if(point.x >= arena.goal_width / 2 + arena.goal_side_radius
- || point.y >= arena.goal_height + arena.goal_side_radius
- || (v.x > 0 && v.y > 0 && zer.dist(v) >= arena.goal_top_radius + arena.goal_side_radius)){
- dist = min(dist, dist_to_plane(point, Vec3d(0, 0, arena.depth / 2), Vec3d(0, 0, -1)));
- }
- // goal
- if(point.z >= (arena.depth / 2 + arena.goal_side_radius)){
- dist = min(dist, dist_to_plane(point, Vec3d(arena.goal_width / 2, 0, 0), Vec3d(-1, 0, 0)));
- dist = min(dist, dist_to_plane(point, Vec3d(0, arena.goal_height, 0), Vec3d(0, -1, 0)));
- }
- // goal back corners
- if(point.z > (arena.depth / 2 + arena.goal_depth - arena.bottom_radius)){
- dist = min(dist, dist_to_sphere_inner(point,
- Vec3d(clamp(point.x, arena.bottom_radius - arena.goal_width / 2, arena.goal_width / 2 - arena.bottom_radius),
- clamp(point.y, arena.bottom_radius, arena.goal_height - arena.goal_top_radius),
- arena.depth / 2 + arena.goal_depth - arena.bottom_radius
- ), arena.bottom_radius));
- }
- //Corner
- if(point.x > arena.width / 2 - arena.corner_radius && point.x > arena.depth / 2 - arena.corner_radius){
- dist = min(dist, dist_to_sphere_inner(point, Vec3d(arena.width / 2 - arena.corner_radius, point.y, arena.depth / 2 - arena.corner_radius), arena.corner_radius));
- }
- //Goal outer corner
- if(point.z < (arena.depth / 2) + arena.goal_side_radius){
- //side x
- if(point.x < arena.goal_width / 2 + arena.goal_side_radius){
- dist = min(dist, dist_to_sphere_outer(point, Vec3d(arena.goal_width / 2 + arena.goal_side_radius, point.y, (arena.depth / 2) + arena.goal_side_radius), arena.goal_side_radius));
- }
- //ceiling
- if(point.y < arena.goal_height + arena.goal_side_radius){
- dist = min(dist, dist_to_sphere_outer(point, Vec3d(point.x, arena.goal_height + arena.goal_side_radius, arena.depth/2 + arena.goal_side_radius), arena.goal_side_radius));
- }
- //top corner
- Vec3d o(arena.goal_width / 2 - arena.goal_top_radius, arena.goal_height - arena.goal_top_radius, 0);
- v = Vec3d(point.x, point.y, 0) - o;
- if(v.x > 0 && v.y > 0){
- o = o + normalize(v) * (arena.goal_top_radius + arena.goal_side_radius);
- dist = min(dist, dist_to_sphere_outer(point, Vec3d(o.x, o.y, arena.depth / 2 + arena.goal_side_radius), arena.goal_side_radius));
- }
- }
- //goal inside top corners
- if(point.z > arena.depth / 2 + arena.goal_side_radius && point.y > arena.goal_height - arena.goal_top_radius){
- //side x
- if(point.x > arena.goal_width / 2 - arena.goal_top_radius){
- dist = min(dist, dist_to_sphere_inner(point, Vec3d(
- arena.goal_width / 2 - arena.goal_top_radius,
- arena.goal_height - arena.goal_top_radius,
- point.z
- ), arena.goal_top_radius));
- }
- //side z
- if(point.z > arena.depth / 2 + arena.goal_depth - arena.goal_top_radius){
- dist = min(dist, dist_to_sphere_inner(point, Vec3d(point.x, arena.goal_height - arena.goal_top_radius, arena.depth / 2 - arena.goal_depth - arena.goal_top_radius), arena.goal_top_radius));
- }
- }
- //bottom corners
- if(point.y < arena.bottom_radius){
- //side x
- if(point.x > arena.width / 2 - arena.bottom_radius){
- dist = min(dist, dist_to_sphere_inner(point, Vec3d(arena.width/2 - arena.bottom_radius, arena.bottom_radius, point.z), arena.bottom_radius));
- }
- //side z
- if(point.x > arena.depth / 2 + arena.goal_depth - arena.bottom_radius){
- dist = min(dist, dist_to_sphere_inner(point, Vec3d(point.x, arena.bottom_radius, (arena.depth / 2) + arena.goal_depth - arena.bottom_radius), arena.bottom_radius));
- }
- //outer
- Vec3d o = Vec3d(arena.goal_width / 2 + arena.goal_side_radius, arena.depth / 2 + arena.goal_side_radius, 0);
- v = Vec3d(point.x, point.z, 0) - o;
- if(v.x < 0 && v.y < 0 && zer.dist(v) < arena.goal_side_radius + arena.bottom_radius){
- o = o + normalize(v) * (arena.goal_side_radius + arena.bottom_radius);
- dist = min(dist, dist_to_sphere_inner(point, Vec3d(o.x, arena.bottom_radius, o.y), arena.bottom_radius));
- }
- //side x(goal)
- if(point.z >= (arena.depth / 2) + arena.goal_side_radius && point.x > (arena.goal_width / 2) - arena.bottom_radius){
- dist = min(dist, dist_to_sphere_inner(point, Vec3d(arena.goal_width / 2 - arena.bottom_radius, arena.bottom_radius, point.z), arena.bottom_radius));
- }
- //corner
- if(point.x > arena.width / 2 - arena.corner_radius && point.z > arena.depth / 2 - arena.corner_radius){
- Vec3d corner_o(arena.width / 2 - arena.corner_radius, arena.depth / 2 - arena.corner_radius, 0);
- Vec3d n = Vec3d(point.x, point.x, 0) - corner_o;
- ld dl = zer.dist(n);
- if(dl > arena.corner_radius - arena.bottom_radius){
- n *= 1 / dl;
- Vec3d o2 = corner_o + n * (arena.corner_radius - arena.bottom_radius);
- dist = min(dist, dist_to_sphere_inner(point, Vec3d(o2.x, arena.bottom_radius, o2.y), arena.bottom_radius));
- }
- }
- }
- // ceiling corners
- if(point.y > arena.height - arena.top_radius){
- //side x
- if(point.x > arena.width / 2 - arena.top_radius){
- dist = min(dist, dist_to_sphere_inner(point, Vec3d(arena.width / 2 - arena.top_radius, arena.height - arena.top_radius, point.z), arena.top_radius));
- }
- //side z
- if(point.z > arena.depth / 2 - arena.top_radius){
- dist = min(dist, dist_to_sphere_inner(point, Vec3d(point.x, arena.height - arena.top_radius, arena.depth / 2 - arena.top_radius), arena.top_radius));
- }
- //corner
- if(point.x > arena.width / 2 - arena.corner_radius && point.z > arena.depth / 2 - arena.corner_radius){
- Vec3d corner_o(arena.width / 2 - arena.corner_radius, arena.depth - arena.corner_radius, 0);
- Vec3d dv = Vec3d(point.x, point.z, 0) - corner_o;
- if(zer.dist(dv) > arena.corner_radius - arena.top_radius){
- Vec3d n = normalize(dv);
- Vec3d o2 = corner_o + n * (arena.corner_radius - arena.top_radius);
- dist = min(dist, dist_to_sphere_inner(point, Vec3d(o2.x, arena.height - arena.top_radius, o2.y), arena.top_radius));
- }
- }
- }
- return dist;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement