public double getAngleTo(myVector vector) { //будем искать угол между текущим вектором и вектором vector, лежащий в интервале (-pi;pi) //для этого найдем косинус - через скалярное произведение double cos = getDotProduct(vector) / (this.getNorm() * vector.getNorm()); //и синус - через векторное double sin = getVectorProduct(vector) / (this.getNorm() * vector.getNorm()); //теперь поработаем с косинусом //нам нужен сам угол, поэтому нужно взять арккосинус, который вернёт значение [0;pi] //ему соответствует два угла (этот), и -(этот) double angle_1_cos = Math.Acos(cos); double angle_2_cos = -angle_1_cos; //теперь поработаем с синусом //ему соответствует угол Asin(sin) [-pi/2;pi/2] - если вернёт положител double angle_1_sin = Math.Asin(sin); double angle_2_sin; if (angle_1_sin >= 0) angle_2_sin = Math.PI - angle_1_sin; else angle_2_sin = -Math.PI - angle_1_sin; //теперь простейшее сравнение if (Math.Abs(angle_1_cos - angle_1_sin) < 0.000001 || Math.Abs(angle_2_cos - angle_1_sin) < 0.000001) return angle_1_sin; else return angle_2_sin; }
private myPolygon Round_ver(myPolygon polygon, int start_position, Graphics graphics, Pen pen) { myPolygon copy_of_this = new myPolygon(this); myPolygon copy_of_poly = new myPolygon(polygon); copy_of_this.vertexes.RemoveAt(copy_of_this.vertexes.Count - 1); for (int i = 0; i < start_position; i++) { copy_of_this.vertexes.Add(copy_of_this.vertexes[0]); copy_of_this.vertexes.RemoveAt(0); } copy_of_this.vertexes.Add(copy_of_this.vertexes[0]); myVertex Start_Vertex = copy_of_this.vertexes[0]; Start_Vertex.Paint(graphics, pen); myPolygon result = new myPolygon(Start_Vertex); Polygons_Iterator pthis = new Polygons_Iterator(copy_of_this,1); Polygons_Iterator ppoly = new Polygons_Iterator(copy_of_poly,0); Boolean I_REALLY_SHOULD_GO_AWAY = false; while (!I_REALLY_SHOULD_GO_AWAY && !pthis.polygon.vertexes[pthis.pos].Equals(Start_Vertex)) { result.AddVertex(pthis.polygon.vertexes[pthis.pos]); new mySection(result.vertexes[result.vertexes.Count - 2], result.vertexes[result.vertexes.Count - 1]).Paint(graphics, pen); result.vertexes[result.vertexes.Count - 1].Paint(graphics, pen); pthis.pos++; if (pthis.pos >= pthis.polygon.vertexes.Count) break; //такая же точка есть и в другом списке int pos_in_poly = ppoly.polygon.ContainVertex(pthis.polygon.vertexes[pthis.pos-1], ppoly.pos); if (pos_in_poly != -1) { ppoly.pos = pos_in_poly + 1; myVector vector_in_first = new myVector(pthis.polygon.vertexes[pthis.pos-1], pthis.polygon.vertexes[pthis.pos]); myVector vector_in_second = new myVector(pthis.polygon.vertexes[pthis.pos-1], ppoly.polygon.vertexes[ppoly.pos]); //проверяем, нужен ли переход if (vector_in_first.getVectorProduct(vector_in_second) < 0) { //нужен переход! поэтому дальше идём по второму списку Boolean i_can_repeat = true; while (!ppoly.polygon.vertexes[ppoly.pos].Equals(Start_Vertex) && i_can_repeat) { result.AddVertex(ppoly.polygon.vertexes[ppoly.pos]); new mySection(result.vertexes[result.vertexes.Count - 2], result.vertexes[result.vertexes.Count - 1]).Paint(graphics, pen); result.vertexes[result.vertexes.Count - 1].Paint(graphics, pen); ppoly.pos++; if (ppoly.pos >= ppoly.polygon.vertexes.Count) break; int pos_in_this = pthis.polygon.ContainVertex(ppoly.polygon.vertexes[ppoly.pos-1], pthis.pos); if (pos_in_this != -1) { pthis.pos = pos_in_this + 1; vector_in_first = new myVector(ppoly.polygon.vertexes[ppoly.pos-1], ppoly.polygon.vertexes[ppoly.pos]); vector_in_second = new myVector(ppoly.polygon.vertexes[ppoly.pos-1], pthis.polygon.vertexes[pthis.pos]); if (vector_in_first.getVectorProduct(vector_in_second) < 0) i_can_repeat = false; } } if (ppoly.polygon.vertexes[ppoly.pos].Equals(Start_Vertex)) I_REALLY_SHOULD_GO_AWAY = true; } } } result.vertexes.Add(result.vertexes[0]); result.Paint(graphics, pen); return result; }
public double getVectorProduct(myVector vector) { return x * vector.y - y * vector.x; }
public double getDotProduct(myVector vector) { return x * vector.x + y * vector.y; }