using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class Calculator3D { public static float x; public static float y; public float getNum(string s, ref int index) { bool end = false; string num = ""; while (!end && index < s.Length) { if ((s[index] >= '0' && s[index] <= '9') || s[index] == '.') { num += s[index]; index++; } else break; } index--; return float.Parse(num); } //'('-0, '+-'-1,'*/'-2,'sct^l'-3 private bool calculateStack(int prior, ref Stack numstack, ref Stack opstack) { while (opstack.Count > 0) { char operater = opstack.Peek(); float num1; float num2; switch (operater) { case '+': if (prior == 1 || prior == 2) return true; opstack.Pop(); num1 = numstack.Peek(); numstack.Pop(); num2 = numstack.Peek(); numstack.Pop(); numstack.Push(num2 + num1); break; case '-': if (prior == 1 || prior == 2) return true; opstack.Pop(); num1 = numstack.Peek(); numstack.Pop(); num2 = numstack.Peek(); numstack.Pop(); numstack.Push(num2 - num1); break; case '*': if (prior == 2) return true; opstack.Pop(); num1 = numstack.Peek(); numstack.Pop(); num2 = numstack.Peek(); numstack.Pop(); numstack.Push(num2 * num1); break; case '/': if (prior == 2) return true; opstack.Pop(); num1 = numstack.Peek(); numstack.Pop(); if (num1 == 0) return false; num2 = numstack.Peek(); numstack.Pop(); numstack.Push(num2 / num1); break; case '(': if (prior == 0) opstack.Pop(); return true; case 's': opstack.Pop(); num1 = numstack.Peek(); numstack.Pop(); numstack.Push(Mathf.Sin(num1)); break; case 'c': opstack.Pop(); num1 = numstack.Peek(); numstack.Pop(); numstack.Push(Mathf.Cos(num1)); break; case 't': opstack.Pop(); num1 = numstack.Peek(); numstack.Pop(); numstack.Push(Mathf.Tan(num1)); break; case '^': opstack.Pop(); num1 = numstack.Peek(); numstack.Pop(); num2 = numstack.Peek(); numstack.Pop(); numstack.Push(Mathf.Pow(num2, num1)); break; case 'l': opstack.Pop(); num1 = numstack.Peek(); numstack.Pop(); if (num1 <= 0) return false; num2 = numstack.Peek(); numstack.Pop(); if (num2 <= 0 || num2 == 1) return false; numstack.Push(Mathf.Log(num1, num2)); break; default: break; } } return true; } public bool calculate3D(string s, float xIn, float yIn, out float zOut) { x = xIn; y = yIn; zOut = 0; Stack opstack = new Stack(); Stack numstack = new Stack(); int length = s.Length; int index; char peek; for (index = 0; index < length; ++index) { if (s[index] == '+' || s[index] == '-') { if (index == 0) { s = "0" + s; length++; } else { if (s[index - 1] == '(') { s.Insert(index - 1, "0"); length++; } } } } index = 0; while (index < length) { switch (s[index]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': numstack.Push(getNum(s, ref index)); break; case 'x': numstack.Push(x); break; case 'y': numstack.Push(y); break; case '(': opstack.Push('('); break; case ')': if (!calculateStack(0, ref numstack, ref opstack)) return false; break; case '+': if (opstack.Count != 0) { peek = opstack.Peek(); if (peek != '+' && peek != '-') { if (!calculateStack(1, ref numstack, ref opstack)) return false; } } opstack.Push('+'); break; case '-': if (opstack.Count != 0) { peek = opstack.Peek(); if (peek != '+' && peek != '-') { if (!calculateStack(1, ref numstack, ref opstack)) return false; } } opstack.Push('-'); break; case '*': if (opstack.Count != 0) { peek = opstack.Peek(); if (peek != '+' && peek != '-' && peek != '*' && peek != '/') { if (!calculateStack(2, ref numstack, ref opstack)) return false; } } opstack.Push('*'); break; case '/': if (opstack.Count != 0) { peek = opstack.Peek(); if (peek != '+' && peek != '-' && peek != '*' && peek != '/') { if (!calculateStack(2, ref numstack, ref opstack)) return false; } } opstack.Push('/'); break; case 's': if (s[index + 1] == 'i' && s[index + 2] == 'n' && s[index + 3] == '(') { opstack.Push('s'); opstack.Push('('); index += 3; } break; case 'c': if (s[index + 1] == 'o' && s[index + 2] == 's' && s[index + 3] == '(') { opstack.Push('c'); opstack.Push('('); index += 3; } break; case 't': if (s[index + 1] == 'a' && s[index + 2] == 'n' && s[index + 3] == '(') { opstack.Push('t'); opstack.Push('('); index += 3; } break; case '^': opstack.Push('^'); break; case 'l': if (s[index + 1] == 'o' && s[index + 2] == 'g' && s[index + 3] == '(') { opstack.Push('l'); opstack.Push('('); index += 3; } break; default: break; } index++; } while (opstack.Count > 0) { if (!calculateStack(3, ref numstack, ref opstack)) return false; } zOut = numstack.Peek(); //Debug.Log(x.ToString() + "," + y.ToString() + "=" + zOut.ToString()); return true; } }