private void computeVerticalProperCrossesWinding(double scanX, Contour targetContour, List <double> crosses) { List <int> indicesToDelete = new List <int>(); List <KeyValuePair <int, double> > crs = new List <KeyValuePair <int, double> >(); double minCross = double.MaxValue; for (int i = 0; i < _edgeTable.Count; i++) { EdgeTableItem eti = _edgeTable[i]; if (eti.Contour != targetContour) { continue; } double v1x = eti.V1x; double v2x = eti.V2x; if (v1x < scanX && v2x < scanX) { indicesToDelete.Add(i); } else { if (v1x > scanX && v2x > scanX) { break; } if (v2x == scanX && v1x == scanX) { continue; } double v1y = eti.V1y; double v2y = eti.V2y; int etiIndex = eti.Index; double crossY = v1y + (scanX - v1x) / (v2x - v1x) * (v2y - v1y); if (!(v1y == crossY && v1x == scanX)) { if (v2y == crossY && v2x == scanX) { Contour c = eti.Contour; int index = eti.IndexInContour; bool isDowntoUp; if (needToAddEndPointVertical(c, index == c.Vertices.Count - 1 ? 0 : index + 1, out isDowntoUp)) { crs.Add(new KeyValuePair <int, double>(etiIndex, crossY)); if (minCross > crossY) { minCross = crossY; _contourOdd = isDowntoUp; } } } else { crs.Add(new KeyValuePair <int, double>(etiIndex, crossY)); if (minCross > crossY) { minCross = crossY; _contourOdd = v1x < v2x; } } } } } for (int i = indicesToDelete.Count - 1; i >= 0; i--) { _edgeTable.RemoveAt(indicesToDelete[i]); } crs.Sort((KeyValuePair <int, double> s1, KeyValuePair <int, double> s2) => s1.Key < s2.Key ? -1 : 1); for (int i = 0; i < crs.Count; i++) { crosses.Add(crs[i].Value); } }
private void computeVerticalProperCrossesAlternate(double scanX, List <double> crosses) { List <int> indicesToDelete = new List <int>(); for (int i = 0; i < _edgeTable.Count; i++) { EdgeTableItem eti = _edgeTable[i]; double v1x = eti.V1x; double v2x = eti.V2x; if (v1x < scanX && v2x < scanX) { indicesToDelete.Add(i); } else { if (v1x > scanX && v2x > scanX) { break; } if (v2x == scanX && v1x == scanX) { continue; } double v1y = eti.V1y; double v2y = eti.V2y; double crossY = v1y + (scanX - v1x) / (v2x - v1x) * (v2y - v1y); if (crossY > _minY && crossY <= _maxY) { if (!(v1y == crossY && v1x == scanX)) { if (v2y == crossY && v2x == scanX) { Contour c = eti.Contour; int index = eti.IndexInContour; if (needToAddEndPointVertical(c, index == c.Vertices.Count - 1 ? 0 : index + 1)) { crosses.Add(crossY); } } else { crosses.Add(crossY); } } } else if (crossY == _minY) { if (!crosses.Contains(crossY)) { crosses.Add(crossY); } } } } for (int i = indicesToDelete.Count - 1; i >= 0; i--) { _edgeTable.RemoveAt(indicesToDelete[i]); } }