using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; public class CanvasManager3D : MonoBehaviour { Dictionary points; Dictionary lines; List vectors; List angles; List constraints; public bool isFin = false; public CanvasManager3D() { points = new Dictionary(); lines = new Dictionary(); vectors = new List(); angles = new List(); constraints = new List(); } public void calculateDig() { Point first = null; if(points.Count != 0) { first = points.First().Value; } else { return ; } first.setPoint(1000, 0, 0); first.setState(State.confirm); HashSet usedPoint = new HashSet(); Queue restPoint = new Queue(); restPoint.Enqueue(first); bool flag = true; while(restPoint.Count != 0 && flag) { Point tmp = restPoint.Peek(); foreach(Line l in tmp.lines) { Point p = l.getAnotherPoint(tmp); if(!restPoint.Contains(p) && !usedPoint.Contains(p)) restPoint.Enqueue(p); } if (tmp.getState() == State.confirm) { restPoint.Dequeue(); usedPoint.Add(tmp); } else { int check = tmp.checkConstraint(); if (check == 0) { tmp.setState(State.confirm); restPoint.Dequeue(); usedPoint.Add(tmp); } else if (check == 1) { //calculate constaint List calculates = new List(); foreach (Constraint c in tmp.constraints) { if (c.getState() == State.halfconfirm) { calculates.Add(c); } } if (calculates.Count == 1) { calculates[0].calculateConstraint(tmp); } else { int count = 0; bool isFinish = false; while (count < 10000) { foreach (Constraint c in calculates) { c.tryCalculateConstraint(tmp); } if (checkConstraints(calculates)) { isFinish = true; foreach (Constraint c in calculates) { c.setState(State.confirm); } break; } count++; } if (!isFinish) { foreach (Constraint c in calculates) { c.setState(State.halfconfirm); } } } restPoint.Dequeue(); restPoint.Enqueue(tmp); } else if (check == 2) { //random restPoint.Dequeue(); restPoint.Enqueue(tmp); } else { restPoint.Dequeue(); restPoint.Enqueue(tmp); } } if(restPoint.Count == 0 && usedPoint.Count != points.Count) { foreach(var p in points) { if (!usedPoint.Contains(p.Value)) { restPoint.Enqueue(p.Value); break; } } } } foreach(Point p in usedPoint) { p.x -= 1000; } PrintPoints(); isFin = true; } public string createPoint(string name = "") { if (name.Equals("")) { char n = 'A'; while (points.ContainsKey(n.ToString())) { n++; } name = n.ToString(); } if (!points.ContainsKey(name)) { Point p = new Point(0, 0, 0, name); points.Add(name, p); } return name; } public void setPoint(string name, float x, float y, float z) { if (points.ContainsKey(name)) { Point p = points[name]; p.setPoint(x, y, z); p.update(); } } public Point GetPoint(string name) { if (points.ContainsKey(name)) { Point p = points[name]; return p; } else return null; } public Vector3[] GetPoints() { Vector3[] tmp = new Vector3[points.Count]; int i = 0; foreach (var p in points) { tmp[i] = new Vector3(p.Value.x, p.Value.y, p.Value.z); i++; } return tmp; } public string createLine(string n1, string n2, float length = 0) { Point p1 = null, p2 = null; points.TryGetValue(n1, out p1); points.TryGetValue(n2, out p2); if (p1 != null && p2 != null) { Line line = new Line(p1, p2); if(length != 0) { createConstraint(line, length, ConstraintType.LineLength); } string lineName = p1.name + p2.name; lines[lineName] = line; p1.addLine(line); p2.addLine(line); return lineName; } return ""; } public void setLine(string n, float length) { Line l1 = null; lines.TryGetValue(n, out l1); if(l1 != null) { createConstraint(l1, length, ConstraintType.LineLength); } } public Line GetLine(string n) { Line l1 = null; lines.TryGetValue(n, out l1); return l1; } public List GetLines() { List tmp = new List(); foreach (var l in lines) { tmp.Add(l.Value); } return tmp; } public string createConstraint(object obj1, object obj2, ConstraintType type) { Constraint constraint = new Constraint(type, obj1, obj2); constraints.Add(constraint); return constraint.name; } void PrintPoints() { foreach(var p in points) { Point tmp = p.Value; Debug.Log(tmp.name + ":(" + tmp.x.ToString() + ", " + tmp.y.ToString() + ", " + tmp.z.ToString() + ")"); } foreach(var l in lines) { Line tmp = l.Value; Debug.Log(l.Key + ":" + tmp.getLength()); } } bool checkConstraints(List constraint) { bool flag = true; foreach(Constraint c in constraint) { if(Mathf.Abs(c.getConstraintValue()) > 0.000001f) { flag = false; break; } } return flag; } }