/// <summary> /// Calculates approximate index on branch where the give point should be placed with given tolerance /// </summary> private int GetAproxIndexOfPoint(Vector3 pPoint, float pMaxDiff) { int fromIndex = 0; int toIndex = TreePoints.Count; int selectedIndex = (fromIndex + toIndex) / 2; CTreePoint selectedTreePoint = TreePoints[selectedIndex]; int counter = 0; while (Math.Abs(selectedTreePoint.Z - pPoint.Z) > pMaxDiff && toIndex - fromIndex > 1) { if (selectedTreePoint.Z > pPoint.Z) { fromIndex += (toIndex - fromIndex) / 2; } else { toIndex -= (toIndex - fromIndex) / 2; } selectedIndex = (fromIndex + toIndex) / 2; selectedTreePoint = TreePoints[selectedIndex]; counter++; } if (counter > 20) { CDebug.Warning("GetAproxIndexOfPoint " + pPoint + " = " + counter); } return(selectedIndex); }
public CTreePoint Clone() { CTreePoint cloneTreePoint = new CTreePoint(Center, treePointExtent); cloneTreePoint.Points = Points; foreach (Vector3 p in Points) { OnAddPoint(p); } return(cloneTreePoint); }
public void CheckBranch() { for (int i = 1; i < TreePoints.Count; i++) { CTreePoint previousTp = TreePoints[i - 1]; CTreePoint tp = TreePoints[i]; if (tp.minHeight.Z > previousTp.maxHeight.Z) { CDebug.Error("- CheckBranch. tree " + tree.treeIndex + ": " + tp + " is higher than " + previousTp); } } }
public static CTreePoint Deserialize(string pLine, float pTreePointExtent) { string[] split = pLine.Split(null); Vector3 _minBB = new Vector3(float.Parse(split[0]), float.Parse(split[1]), float.Parse(split[2])); Vector3 _maxBB = new Vector3(float.Parse(split[3]), float.Parse(split[4]), float.Parse(split[5])); CTreePoint treePoint = new CTreePoint((_minBB + _maxBB) / 2, pTreePointExtent); treePoint.OnAddPoint(_minBB); treePoint.OnAddPoint(_maxBB); return(treePoint); }
private void CheckAddedPoint() { if (TreePoints[0].minHeight.Z > tree.peak.Z) { //not error, can happen after merging when peak is expanded //CDebug.Error($"CheckAddedPoint. tree {tree.treeIndex} : first point {TreePoints[0]} is higher than peak {tree.peak}"); } if (TreePoints.Count < 2) { return; } CTreePoint previousTp = TreePoints[TreePoints.Count - 2]; CTreePoint tp = TreePoints[TreePoints.Count - 1]; if (tp.minHeight.Z > previousTp.maxHeight.Z) { CDebug.Error("CheckAddedPoint. tree " + tree.treeIndex + ": " + tp + " is higher than " + previousTp); } }
/// <summary> /// If given tree point is included in one of points on this branch /// </summary> public bool Contains(Vector3 pPoint, float pToleranceMultiply) { float treePointExtent = tree.peak.treePointExtent * pToleranceMultiply; int approxIndex = GetAproxIndexOfPoint(pPoint, treePointExtent); //which direction on branch should we search int dir = 1; //actually to be sure we need to check both directions...final treepoints doesnt have to be neccessarily Y-ordered //if (TreePoints[approxIndex].Y < pPoint.Y) { dir = -1; } CTreePoint pointOnBranch = TreePoints[approxIndex]; bool isPointOnBranchWithinRange = Math.Abs(pointOnBranch.Z - pPoint.Z) < treePointExtent + 1; for (int i = approxIndex; isPointOnBranchWithinRange && i > 0 && i < TreePoints.Count; i += dir) { pointOnBranch = TreePoints[i]; if (pointOnBranch.Includes(pPoint, pToleranceMultiply)) { return(true); } isPointOnBranchWithinRange = Math.Abs(pointOnBranch.Z - pPoint.Z) < treePointExtent + 1; } dir = -1; pointOnBranch = TreePoints[approxIndex]; isPointOnBranchWithinRange = Math.Abs(pointOnBranch.Z - pPoint.Z) < treePointExtent + 1; for (int i = approxIndex; isPointOnBranchWithinRange && i > 0 && i < TreePoints.Count; i += dir) { pointOnBranch = TreePoints[i]; if (pointOnBranch.Includes(pPoint, pToleranceMultiply)) { return(true); } isPointOnBranchWithinRange = Math.Abs(pointOnBranch.Z - pPoint.Z) < treePointExtent + 1; } return(false); }
public void AddPoint(Vector3 pPoint) { if (CTreeManager.DEBUG) { CDebug.WriteLine("--- AddPoint " + pPoint.ToString("#+0.00#;-0.00") + " to " + this); } RefreshFurthestPoint(pPoint); OnAddPoint(pPoint); int insertAtIndex = 0; //find appropriate insert at index if (TreePoints.Count > 0) { for (int i = TreePoints.Count - 1; i >= -1; i--) { insertAtIndex = i + 1; if (insertAtIndex == 0) { break; } CTreePoint pointOnBranch = TreePoints[i]; if (pointOnBranch.Includes(pPoint)) { pointOnBranch.AddPoint(pPoint); //boundaries of points are changed, check if the order has to be changed if (i > 0) { CTreePoint previousPoint = TreePoints[i - 1]; //if(previousPoint.Contains(pointOnBranch.Center)) if (pointOnBranch.Z > previousPoint.Z) { TreePoints.RemoveAt(i); TreePoints.Insert(i - 1, pointOnBranch); } } if (i < TreePoints.Count - 1) { CTreePoint nextPoint = TreePoints[i + 1]; if (pointOnBranch.Z < nextPoint.Z) { TreePoints.RemoveAt(i); TreePoints.Insert(i + 1, pointOnBranch); } } CheckAddedPoint(); return; } if (pPoint.Z < pointOnBranch.Z) { if (i == TreePoints.Count - 1 || TreePoints[i + 1].Z <= pPoint.Z) { break; } } } } CTreePoint newPoint = new CTreePoint(pPoint, tree.treePointExtent); TreePoints.Insert(insertAtIndex, newPoint); CheckAddedPoint(); if (CTreeManager.DEBUG) { CDebug.WriteLine("---- new point"); } }
public static float Get2DDistance(Vector3 a, CTreePoint b) { return(Vector2.Distance(new Vector2(a.X, a.Y), new Vector2(b.X, b.Y))); }
public CRefTree(string pFileName, string[] pSerializedLines) { DeserialiseMode currentMode = DeserialiseMode.None; fileName = pFileName; isValid = true; branches = new List <CBranch>(); List <CTreePoint> _treepointsOnBranch = new List <CTreePoint>(); //if first line is not version then it is the old version and //the file needs to be regenerated if (pSerializedLines.Length == 0 || pSerializedLines[0] != KEY_VERSION) { return; } foreach (string line in pSerializedLines) { switch (line) { case KEY_VERSION: currentMode = DeserialiseMode.Version; continue; case KEY_TREE_INDEX: currentMode = DeserialiseMode.TreeIndex; continue; case KEY_TREE_POINT_EXTENT: currentMode = DeserialiseMode.TreePointExtent; continue; case KEY_PEAK: currentMode = DeserialiseMode.Peak; continue; case KEY_BRANCHES: currentMode = DeserialiseMode.Branches; continue; case KEY_STEM: currentMode = DeserialiseMode.Stem; branches.Last().SetTreePoints(_treepointsOnBranch); _treepointsOnBranch = new List <CTreePoint>(); continue; case KEY_BOUNDING_BOX: currentMode = DeserialiseMode.BoundingBox; continue; } switch (currentMode) { case DeserialiseMode.Version: version = line; if (!IsCurrentVersion()) { CDebug.Warning($"reftree version {version} is not up to date {CURRENT_REFTREE_VERSION}. Generating new file."); return; } break; case DeserialiseMode.TreeIndex: treeIndex = int.Parse(line); break; case DeserialiseMode.TreePointExtent: treePointExtent = float.Parse(line); break; case DeserialiseMode.Peak: peak = CPeak.Deserialize(line, treePointExtent); stem = new CBranch(this, 0, 0); break; case DeserialiseMode.Branches: if (line.Contains(KEY_BRANCH)) { int branchIndex = branches.Count; if (branchIndex > 0) { branches.Last().SetTreePoints(_treepointsOnBranch); } branches.Add(new CBranch( this, branchIndex * BRANCH_ANGLE_STEP, branchIndex * BRANCH_ANGLE_STEP + BRANCH_ANGLE_STEP)); _treepointsOnBranch = new List <CTreePoint>(); } else { CTreePoint treePointOnBranch = CTreePoint.Deserialize(line, treePointExtent); _treepointsOnBranch.Add(treePointOnBranch); Points.Add(treePointOnBranch.Center); } break; case DeserialiseMode.Stem: _treepointsOnBranch.Add(CTreePoint.Deserialize(line, treePointExtent)); break; case DeserialiseMode.BoundingBox: string[] split = line.Split(null); minBB = new Vector3(float.Parse(split[0]), float.Parse(split[1]), float.Parse(split[2])); maxBB = new Vector3(float.Parse(split[3]), float.Parse(split[4]), float.Parse(split[5])); break; } } stem.SetTreePoints(_treepointsOnBranch); LoadObj(pFileName); }