static bool tryParseCircle(ref TouchItem touchItem) { int count = touchItem.positions.Count; //print("positions count is " + count); if (count < 5) return false; float cx = 0, cy = 0; foreach (Vector2 pos in touchItem.positions) { cx += pos.x; cy += pos.y; } cx /= count; cy /= count; Vector2 center = new Vector2(cx, cy); float midleRadius = 0, minRadius = float.MaxValue, maxRadius = 0; foreach (Vector2 pos in touchItem.positions) { float rad = Vector2.Distance(center, pos); midleRadius += rad; if (rad < minRadius) minRadius = rad; if (rad > maxRadius) maxRadius = rad; } midleRadius /= count; short pF = axisPart((Vector2)touchItem.positions[1] - (Vector2)touchItem.positions[0]); int wrongsCW = 0, wrongsCCW = 0; int partChCW = 0, partChCCW = 0; short cur = pF; string poss = ""; for (int i = 2; i < count; i++) { short next = axisPart((Vector2)touchItem.positions[i] - (Vector2)touchItem.positions[i - 1]); int cw = axisNext(cur, next, true), ccw = axisNext(cur, next, false); poss += next.ToString(); if (cw <= -1) wrongsCW++; if (ccw <= -1) wrongsCCW++; if (cw == 1) partChCW++; if (ccw == 1) partChCCW++; cur = next; } partChCW = Mathf.RoundToInt((float)partChCW / 4f); partChCCW = Mathf.RoundToInt((float)partChCCW / 4f); int wrongs = Mathf.Min(wrongsCCW, wrongsCW), partsCh = Mathf.Max(partChCW, partChCCW); if (wrongs == wrongsCCW) partsCh = -partsCh; wrongs = (int)((float)wrongs / count * 100); //print(poss); //print("wrongs: " + wrongs + "% rotates:" + partsCh); if (wrongs > 25) { //print("to many wrongs"); return false; } int[] counts = new int[4]; foreach (Vector2 pos in touchItem.positions) counts[axisPart(pos - center)]++; int midlePartsCount = 0; foreach (int x in counts) midlePartsCount += x; midlePartsCount /= 4; foreach (int x in counts) if (Mathf.Abs(midlePartsCount - x) > 5) { //print("incorrect parts count"); return false; } float minRadiusD = float.MaxValue, maxRadiusD = 0; foreach (Vector2 pos in touchItem.positions) { float curDelta = Vector2.Distance(pos, center) / midleRadius * 100; if (curDelta > maxRadiusD) maxRadiusD = curDelta; if (curDelta < minRadiusD) minRadiusD = curDelta; } //print("min radius delta: " + minRadiusD + "% max radius delta: " + maxRadiusD + "%"); if (minRadiusD < 45 || maxRadiusD > 160) { //print("wrong radiuses"); return false; } //print("circle!!"); GistureCircle param = new GistureCircle(); param.center = center; param.radius = midleRadius; param.rotates = partsCh; touchItem.gistureParams = param; return true; }
static bool tryParseCircle(ref TouchItem touchItem) { int count = touchItem.positions.Count; //print("positions count is " + count); if (count < 5) { return(false); } float cx = 0, cy = 0; foreach (Vector2 pos in touchItem.positions) { cx += pos.x; cy += pos.y; } cx /= count; cy /= count; Vector2 center = new Vector2(cx, cy); float midleRadius = 0, minRadius = float.MaxValue, maxRadius = 0; foreach (Vector2 pos in touchItem.positions) { float rad = Vector2.Distance(center, pos); midleRadius += rad; if (rad < minRadius) { minRadius = rad; } if (rad > maxRadius) { maxRadius = rad; } } midleRadius /= count; short pF = axisPart((Vector2)touchItem.positions[1] - (Vector2)touchItem.positions[0]); int wrongsCW = 0, wrongsCCW = 0; int partChCW = 0, partChCCW = 0; short cur = pF; string poss = ""; for (int i = 2; i < count; i++) { short next = axisPart((Vector2)touchItem.positions[i] - (Vector2)touchItem.positions[i - 1]); int cw = axisNext(cur, next, true), ccw = axisNext(cur, next, false); poss += next.ToString(); if (cw <= -1) { wrongsCW++; } if (ccw <= -1) { wrongsCCW++; } if (cw == 1) { partChCW++; } if (ccw == 1) { partChCCW++; } cur = next; } partChCW = Mathf.RoundToInt((float)partChCW / 4f); partChCCW = Mathf.RoundToInt((float)partChCCW / 4f); int wrongs = Mathf.Min(wrongsCCW, wrongsCW), partsCh = Mathf.Max(partChCW, partChCCW); if (wrongs == wrongsCCW) { partsCh = -partsCh; } wrongs = (int)((float)wrongs / count * 100); //print(poss); //print("wrongs: " + wrongs + "% rotates:" + partsCh); if (wrongs > 25) { //print("to many wrongs"); return(false); } int[] counts = new int[4]; foreach (Vector2 pos in touchItem.positions) { counts[axisPart(pos - center)]++; } int midlePartsCount = 0; foreach (int x in counts) { midlePartsCount += x; } midlePartsCount /= 4; foreach (int x in counts) { if (Mathf.Abs(midlePartsCount - x) > 5) { //print("incorrect parts count"); return(false); } } float minRadiusD = float.MaxValue, maxRadiusD = 0; foreach (Vector2 pos in touchItem.positions) { float curDelta = Vector2.Distance(pos, center) / midleRadius * 100; if (curDelta > maxRadiusD) { maxRadiusD = curDelta; } if (curDelta < minRadiusD) { minRadiusD = curDelta; } } //print("min radius delta: " + minRadiusD + "% max radius delta: " + maxRadiusD + "%"); if (minRadiusD < 45 || maxRadiusD > 160) { //print("wrong radiuses"); return(false); } //print("circle!!"); GistureCircle param = new GistureCircle(); param.center = center; param.radius = midleRadius; param.rotates = partsCh; touchItem.gistureParams = param; return(true); }