public bool is_parallel(Line1 l) { if (type == 1 && l.type == 1) { return(Math.Abs(K - l.k) < eps); } return(l.type == 0 && type == 0); }
public static Line1 perp_bis_cons(Point a, Point b) { Line1 res = new Line1(); if ((b.y - a.y) != 0) { res.k = -(b.x - a.x) / (b.y - a.y); res.c = (b.y * b.y + b.x * b.x - a.y * a.y - a.x * a.x) / (2 * (b.y - a.y)); res.type = 1; } else { res.k = 0; res.c = -(a.x + b.x) / 2; res.type = 0; } return(res); }
public Point piercing_lines(Line1 l) { Point res = new Point(); if (type == 1 && l.type == 1) { res.x = (l.c - C) / (K - l.k); res.y = (K * l.c - C * l.k) / (K - l.k); } if (type == 1 && l.type == 0) { res.x = -l.c; res.y = -K * l.c + C; } if (type == 0 && l.type == 1) { res.x = -C; res.y = -l.k * C + l.c; } return(res); }
public List <Tuple <Line, int> > Voronoi_cell(int i, List <Line> vis_i) { List <Tuple <Line, int> > res = new List <Tuple <Line, int> >(); List <Tuple <Line, int> > hull = new List <Tuple <Line, int> >(); Point A = new Point(min_x, min_y); Point B = new Point(min_x, max_y); Point C = new Point(max_x, max_y); Point D = new Point(max_x, min_y); Tuple <Line, int> tmp = new Tuple <Line, int>(new Line(A, B), -1); hull.Add(tmp); tmp = new Tuple <Line, int>(new Line(B, C), -1); hull.Add(tmp); tmp = new Tuple <Line, int>(new Line(C, D), -1); hull.Add(tmp); tmp = new Tuple <Line, int>(new Line(D, A), -1); hull.Add(tmp); for (int j = 0; j < size; j++) { if (j != i) { Line1 basic = Line1.perp_bis_cons(points[i], points[j]); int drop_s = -1; int drop_f = -1; bool type = false; // type=0 if from 0 to drop_s and from drop_s to hull.Count bool across = false; Point new1 = new Point(); Point new2 = new Point(); for (int t = 0; t < hull.Count; t++) { if (!hull[t].Item1.is_parallel(basic)) { Point meet = hull[t].Item1.piercing_lines(basic); if (hull[t].Item1.in_edge(meet)) { if (drop_s == -1) { if (basic.sign_line(points[i]) * (basic.sign_line(hull[t].Item1.a)) > 0) { drop_s = t; type = false; } else { drop_s = t; type = true; } new1 = meet; } else { if (basic.sign_line(points[i]) * (basic.sign_line(hull[t].Item1.a)) > 0) { drop_f = t; //type = false; } else { drop_f = t; //type = true; } new2 = meet; across = true; break; } } } } if (across) { if (type) { List <Tuple <Line, int> > copy_hull = new List <Tuple <Line, int> >(); Tuple <Line, int> tmpq = new Tuple <Line, int>(new Line(new1, hull[drop_s].Item1.b), hull[drop_s].Item2); copy_hull.Add(tmpq); for (int k = drop_s + 1; k < drop_f; k++) { copy_hull.Add(hull[k]); } tmpq = new Tuple <Line, int>(new Line(hull[drop_f].Item1.a, new2), hull[drop_f].Item2); copy_hull.Add(tmpq); tmpq = new Tuple <Line, int>(new Line(new2, new1), j); copy_hull.Add(tmpq); hull = new List <Tuple <Line, int> >(copy_hull); } else { List <Tuple <Line, int> > copy_hull = new List <Tuple <Line, int> >(); for (int k = 0; k < drop_s; k++) { copy_hull.Add(hull[k]); } Tuple <Line, int> tmpq = new Tuple <Line, int>(new Line(hull[drop_s].Item1.a, new1), hull[drop_s].Item2); copy_hull.Add(tmpq); tmpq = new Tuple <Line, int>(new Line(new1, new2), j); copy_hull.Add(tmpq); tmpq = new Tuple <Line, int>(new Line(new2, hull[drop_f].Item1.b), hull[drop_f].Item2); copy_hull.Add(tmpq); for (int k = drop_f + 1; k < hull.Count; k++) { copy_hull.Add(hull[k]); } hull = new List <Tuple <Line, int> >(copy_hull); } } } } res = hull; return(res); }