private Vector2 CalcOriginOrig(out int[] _firstTriIdxs) { var cent = D.BoundsRect.center; var closest = new SortedList <float, int> { { (cent - D.Points[0]).sqrMagnitude, 0 }, { (cent - D.Points[1]).sqrMagnitude, 1 }, { (cent - D.Points[2]).sqrMagnitude, 2 } }; for (var idx = 3; idx < D.Points.Length; ++idx) { var pt = D.Points[idx]; var distSqr = (cent - pt).sqrMagnitude; if (distSqr > closest.Keys[2]) { continue; } closest.Add(distSqr, idx); } _firstTriIdxs = new[] { closest.Values[0], closest.Values[1], closest.Values[2] }; //Find 1st non-linear set of points (valid triangle) var findNonLineIdx = 3; while (Geom.AreColinear(D.Points[_firstTriIdxs[0]], D.Points[_firstTriIdxs[1]], D.Points[_firstTriIdxs[2]], D.MinFloatingPointErr)) { _firstTriIdxs[2] = closest.Values[findNonLineIdx++]; } //Force Clockwise var v0 = D.Points[_firstTriIdxs[0]]; var v1 = D.Points[_firstTriIdxs[1]]; var v2 = D.Points[_firstTriIdxs[2]]; var vecL = v1 - v0; var vecR = v2 - v0; //Positive Cross Product greater than 180 var crossZ = vecL.x * vecR.y - vecL.y * vecR.x; if (crossZ > 0) { var tempIdx = _firstTriIdxs[1]; _firstTriIdxs[1] = _firstTriIdxs[2]; _firstTriIdxs[2] = tempIdx; } var triPts = new[] { D.Points[_firstTriIdxs[0]], D.Points[_firstTriIdxs[1]], D.Points[_firstTriIdxs[2]] }; var cc = Geom.CentroidOfPoly(triPts); return(cc); }
private Vector2 CalcOrigin(out int[] _firstTriIdxs) { var cent = D.BoundsRect.center; var pIdxArr = new int[D.Points.Length]; var pDistArr = new float[D.Points.Length]; for (var idx = 0; idx < pIdxArr.Length; ++idx) { var dx = Math.Abs(cent.x - D.Points[idx].x); var dy = Math.Abs(cent.y - D.Points[idx].y); pIdxArr[idx] = idx; pDistArr[idx] = dx + dy; } Array.Sort(pIdxArr, (_a, _b) => pDistArr[_a].CompareTo(pDistArr[_b])); _firstTriIdxs = new[] { pIdxArr[0], pIdxArr[1], pIdxArr[2] }; //Find 1st non-linear set of points (valid triangle) var findNonLineIdx = 3; while (Geom.AreColinear(D.Points[_firstTriIdxs[0]], D.Points[_firstTriIdxs[1]], D.Points[_firstTriIdxs[2]], D.MinFloatingPointErr)) { _firstTriIdxs[2] = pIdxArr[findNonLineIdx++]; } //Force Clockwise var v0 = D.Points[_firstTriIdxs[0]]; var v1 = D.Points[_firstTriIdxs[1]]; var v2 = D.Points[_firstTriIdxs[2]]; var vecL = v1 - v0; var vecR = v2 - v0; //Positive Cross Product greater than 180 var crossZ = vecL.x * vecR.y - vecL.y * vecR.x; if (crossZ > 0) { var tempIdx = _firstTriIdxs[1]; _firstTriIdxs[1] = _firstTriIdxs[2]; _firstTriIdxs[2] = tempIdx; } var triPts = new[] { D.Points[_firstTriIdxs[0]], D.Points[_firstTriIdxs[1]], D.Points[_firstTriIdxs[2]] }; var cc = Geom.CentroidOfPoly(triPts); return(cc); }
private Vector2 CalcOrigin2(out int[] _firstTriIdxs) { var cent = D.BoundsRect.center; Func <Vector2, float> fPtDist = _p => Math.Abs(_p.x) + Math.Abs(_p.y); var lstPIdx = new List <int>(3) { 0, 1, 2 }; var lstPDist = new List <float>(3) { fPtDist(D.Points[0]), fPtDist(D.Points[1]), fPtDist(D.Points[2]) }; lstPIdx.Sort((_a, _b) => lstPDist[_a].CompareTo(lstPDist[_b])); lstPDist = new List <float>(3) { fPtDist(D.Points[lstPIdx[0]]), fPtDist(D.Points[lstPIdx[1]]), fPtDist(D.Points[lstPIdx[2]]) }; for (var pIdx = 3; pIdx < D.Points.Length; ++pIdx) { var pDist = fPtDist(D.Points[pIdx]); if (pDist > lstPDist[2]) { continue; } if (pDist < lstPDist[0]) { lstPDist[2] = lstPDist[1]; lstPIdx[2] = lstPIdx[1]; lstPDist[1] = lstPDist[0]; lstPIdx[1] = lstPIdx[0]; lstPDist[0] = pDist; lstPIdx[0] = pIdx; continue; } if (pDist < lstPDist[1]) { lstPDist[2] = lstPDist[1]; lstPIdx[2] = lstPIdx[1]; lstPDist[1] = pDist; lstPIdx[1] = pIdx; continue; } lstPDist[2] = pDist; lstPIdx[2] = pIdx; } _firstTriIdxs = lstPIdx.ToArray(); //Find 1st non-linear set of points (valid triangle) var findNonLineIdx = 3; while (Geom.AreColinear(D.Points[_firstTriIdxs[0]], D.Points[_firstTriIdxs[1]], D.Points[_firstTriIdxs[2]], D.MinFloatingPointErr)) { var dIdx = _firstTriIdxs[0]; var dbgPt0 = D.Points[_firstTriIdxs[0]]; //TODO remove var dbgPt1 = D.Points[_firstTriIdxs[1]]; var dbgPt2 = D.Points[_firstTriIdxs[2]]; var mPntX = D.Points[dIdx].x; var mPntY = D.Points[dIdx].y; var rnd = new Random((int)DateTime.Now.Ticks); var rndDir = rnd.Next(4); if (rndDir == 0) { D.Points[dIdx].Set(mPntX + D.MinFloatingPointErr, mPntY); } else if (rndDir == 1) { D.Points[dIdx].Set(mPntX - D.MinFloatingPointErr, mPntY); } else if (rndDir == 2) { D.Points[dIdx].Set(mPntX, mPntY + D.MinFloatingPointErr); } else { D.Points[dIdx].Set(mPntX, mPntY - D.MinFloatingPointErr); } } ; //Force Clockwise var v0 = D.Points[_firstTriIdxs[0]]; var v1 = D.Points[_firstTriIdxs[1]]; var v2 = D.Points[_firstTriIdxs[2]]; var vecL = v1 - v0; var vecR = v2 - v0; //Positive Cross Product greater than 180 var crossZ = vecL.x * vecR.y - vecL.y * vecR.x; if (crossZ > 0) { var tempIdx = _firstTriIdxs[1]; _firstTriIdxs[1] = _firstTriIdxs[2]; _firstTriIdxs[2] = tempIdx; } var triPts = new[] { D.Points[_firstTriIdxs[0]], D.Points[_firstTriIdxs[1]], D.Points[_firstTriIdxs[2]] }; var cc = Geom.CentroidOfPoly(triPts); return(cc); }