private OptimumConversionBuilder CreateOptimumBuilder(Triangle from, List<Triangle> list) { OptimumConversionBuilder ocb = null; foreach (Triangle t in list) { OptimumConversionBuilder ocbTmp = new OptimumConversionBuilder(from, t); if (ocb == null || ocbTmp.Distance < ocb.Distance) ocb = ocbTmp; } return ocb; }
private Triangle FindEquals(Triangle triangle, List<Triangle> list) { Triangle result = null; foreach (Triangle t in list) { if (t.Equals(triangle)) return t; } return result; }
private Triangle FindNear(Triangle triangle, double distance, List<Triangle> list) { Triangle result = null; double nearDistance = -1; foreach (Triangle t in list) { if (t.Equals(triangle, distance)) { double tmpNearDistance = t.GetDistanceTo(triangle); if (tmpNearDistance < nearDistance || nearDistance == -1) { result = t; nearDistance = tmpNearDistance; } } } return result; }
public double GetDistanceTo(Triangle triangle) { return triangle.A.GetDistance(A) * triangle.A.GetDistance(A) + (triangle.B.GetDistance(B) * triangle.B.GetDistance(B)) + (triangle.C.GetDistance(C) * triangle.C.GetDistance(C)); }
public bool Equals(Triangle triangle, double distance) { if (A.GetDistance(triangle.A) < distance && B.GetDistance(triangle.B) < distance && C.GetDistance(triangle.C) < distance) return true; if (A.GetDistance(triangle.A) < distance && B.GetDistance(triangle.C) < distance && C.GetDistance(triangle.B) < distance) return true; if (A.GetDistance(triangle.B) < distance && B.GetDistance(triangle.C) < distance && C.GetDistance(triangle.A) < distance) return true; if (A.GetDistance(triangle.B) < distance && B.GetDistance(triangle.A) < distance && C.GetDistance(triangle.C) < distance) return true; if (A.GetDistance(triangle.C) < distance && B.GetDistance(triangle.B) < distance && C.GetDistance(triangle.A) < distance) return true; if (A.GetDistance(triangle.C) < distance && B.GetDistance(triangle.A) < distance && C.GetDistance(triangle.B) < distance) return true; return false; }
public Section(Vector vector, Triangle left = null, Triangle right = null) { this.Vector = vector; this.Left = left; this.Right = right; }
private bool UpdateTriangles(Triangle tRight, Triangle tLeft, Section commonSection, List<Triangle> tmpResult, Graphics g = null, Pen linePen = null, Pen pointPen = null, Pen newLinePen = null, int formHeight = 0, int delay = 0) { //меняем общее ребро у двух треугольников Point leftExcessPoint = TriangulationBuilder.GetExcessPoint(tLeft, commonSection); Point rightExcessPoint = TriangulationBuilder.GetExcessPoint(tRight, commonSection); if (commonSection.CountAnglesSum(leftExcessPoint) + commonSection.CountAnglesSum(rightExcessPoint) < 180) { Point up = commonSection.A; Point down = commonSection.B; if (new Vector(down, rightExcessPoint).GetVectorMultiplication(new Vector(down, leftExcessPoint)) < 0) { up = commonSection.B; down = commonSection.A; } tmpResult.Remove(tLeft); tmpResult.Remove(tRight); Triangle toAddFirst = new Triangle(leftExcessPoint, down, rightExcessPoint); Triangle toAddSecond = new Triangle(rightExcessPoint, up, leftExcessPoint); tmpResult.Add(toAddFirst); tmpResult.Add(toAddSecond); if (g != null && linePen != null && newLinePen != null && formHeight != -1 && delay != -1) { g.DrawLine(new Pen(Color.White, 2), (int)commonSection.A.X, formHeight - (int)commonSection.A.Y, (int)commonSection.B.X, formHeight - (int)commonSection.B.Y); g.DrawLine(newLinePen, (int)leftExcessPoint.X, formHeight - (int)leftExcessPoint.Y, (int)rightExcessPoint.X, formHeight - (int)rightExcessPoint.Y); Thread.Sleep(delay); g.DrawLine(new Pen(Color.White, 2), (int)leftExcessPoint.X, formHeight - (int)leftExcessPoint.Y, (int)rightExcessPoint.X, formHeight - (int)rightExcessPoint.Y); g.DrawLine(linePen, (int)leftExcessPoint.X, formHeight - (int)leftExcessPoint.Y, (int)rightExcessPoint.X, formHeight - (int)rightExcessPoint.Y); toAddFirst.Paint(g, linePen, pointPen, formHeight); toAddSecond.Paint(g, linePen, pointPen, formHeight); } return true; } return false; }
private void UpdateShell() { /* * Идея следующая: берем два соседних ребра в оболочке, (по способу построения они идут против часовой стрелки) * вычисляем их векторное произведение. Если оно положительно - оболочка не выпукла, нужно добавить в неё ребро, * а эти два удалить. Так же, нужно добавить треугольник. И так до тех пор, пока не сделаем полный проход, при этом * не изменив ни одного ребра. */ bool shellChanged = true; while (shellChanged) { shellChanged = false; for (int i = 0; i < shell.Count - 1; i++) { if (shell[i].GetVectorMultiplication(shell[i + 1]) < 0) { triangles.Add(new Triangle(shell[i].Start, shell[i].End, shell[i + 1].End)); shell[i] = new Vector(shell[i].Start, shell[i + 1].End); shell.RemoveAt(i + 1); shellChanged = true; } } if (shell[shell.Count - 1].GetVectorMultiplication(shell[0]) < 0) { Triangle t = new Triangle(shell[shell.Count - 1].Start, shell[0].End, shell[shell.Count - 1].End); triangles.Add(t); shell[shell.Count - 1] = new Vector(shell[shell.Count - 1].Start, shell[0].End); shell.RemoveAt(0); shellChanged = true; } } }
private Triangle GetNearestTriangleWithCommonSideInList(Triangle destination, bool a, bool b, bool c, List<Triangle> list) { foreach (Triangle t in list) { if (t.Equals(destination)) continue; if (a && (destination.a.Equals(t.a) || destination.a.Equals(t.b) || destination.a.Equals(t.c))) return t; if (b && (destination.b.Equals(t.a) || destination.b.Equals(t.b) || destination.b.Equals(t.c))) return t; if (c && (destination.c.Equals(t.a) || destination.c.Equals(t.b) || destination.c.Equals(t.c))) return t; } return null; }
private static Point GetExcessPoint(Triangle t, Section s) { //ищем точку из треугольника, не лежащую на ребре Point excessPoint; if (!t.A.Equals(s.A) && !t.A.Equals(s.B)) excessPoint = t.A; else if (!t.B.Equals(s.A) && !t.B.Equals(s.B)) excessPoint = t.B; else excessPoint = t.C; return excessPoint; }