using System; using System.Collections.Generic; using System.Linq; using System.Text; using OpenGL4NET; using OpenGLRenderer; using OpenGLRenderer.Geometry; using System.IO; using System.Windows.Forms; using System.Text.RegularExpressions; namespace ZPG_2_Rotacni_teleso { class Program { /// /// Počet bodů tvoricich polovinu prurezu telesa /// Number Of Points /// private static int NOP; /// /// Pocet bodu na kruznici (jedné vrstevnici) /// Number Of Points On Circle /// private static int NOPOC = 20; /// /// Pocet vsech bodu /// Number Of All Points /// private static int NOAP; /// /// Number Of Triangles /// Pocet trojuhelniku /// private static int NOT; /// /// Number Of Triangles In Row /// Pocet trojuhelniku v radku (v jednom pasu) /// private static int NOTIR; /// /// points2D[-,0] - x-ova souradnice /// points2D[-,1] - y-ova souradnice /// private static float[,] loadPoints; /// /// points[-,0] - x-ova souradnice /// points[-,1] - y-ova souradnice /// points[-,2] - z-ova souradnice /// private static float[,] points; /// /// triangles[i,0,-] - sousedi i-teho trojuhelniky /// triangles[i,1,-] - body i-teho trojuhelniku /// private static int[, ,] triangles; private static int[,] neighbours; /// /// Normalove vektory trojuhelniku /// vectors[i,x] - x-ova slozka normaloveho vektoru i-teho trojuhelniku /// vectors[i,y] - y-ova slozka /// vectors[i,z] - z-ova slozka /// private static float[,] vectors; static void Main(String[] args) { Renderer r = new Renderer(); //objekt pro renderovani if (args.Length == 0) { MessageBox.Show("No input arguments.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { LoadPoints(args[0]); //načte body NOAP = NOP * NOPOC; NOT = 2 * NOPOC * (NOP - 1); NOTIR = 2 * NOPOC; PointPlace(NOPOC); //rozmístí body po kružnici triangles = new int[NOT,2,3]; CreateTriangles(); //vytvoří trojúhelníky GetNormalVectors(); //spočítá normálové vektory pro všechny trojúhelníky SetTrianglesNeighbour(); //najde sousedící trojúhelníky SaveOutput(args[0]); //uloží data do výstupního souboru } gl.Enable(GL.CULL_FACE); //vykreslovani pouze trojuhelniku se spravnou orientaci //r.SetProjectionMatrix(...); //pouzit misto "r.SetDefaultTransformations()" while (r.IsAlive) { r.SetDefaultTransformations(); //r.SetModelViewMatrix(...); //pouzit misto "r.SetDefaultTransformations()" int a,b,c; for (int i = 0; i < NOT; i++) { a = triangles[i, 1, 0]; b = triangles[i, 1, 1]; c = triangles[i, 1, 2]; r.AddTriangle( new Float3((float)points[a, 1], (float)points[a, 0], (float)points[a, 2]), new Float3((float)points[b, 1], (float)points[b, 0], (float)points[b, 2]), new Float3((float)points[c, 1], (float)points[c, 0], (float)points[c, 2]), new Float3((float)vectors[i, 0], (float)vectors[i, 1], (float)vectors[i, 2]) ); } // ukazka vykresleni trojuhelniku - trojuhelnik obsahuje normalu //r.AddTriangle(new Float3(0, 0, 0), new Float3(0.5f, 0, 0), new Float3(0.3f, 1, 0), new Float3(0, 0, 1)); // ukazka vykresleni trojuhelniku - vrcholy obsahuji normalu //r.AddTriangle(new Point(new Float3(0, 0, 0), new Float3(-1, 0.5f, 0)), new Point(new Float3(0, 0, 0.5f), new Float3(-0.3f, 1, 1)), new Point(new Float3(0, 1, 0.3f), new Float3(0.8f, -0.5f, -0.4f))); r.Render(); //zobrazeni aktualniho snimku } } /// /// Nacte vstupni soubor /// public static void LoadPoints(String inputFile) { string line; try { StreamReader sr = new StreamReader(inputFile); line = sr.ReadLine(); string[] data; data = Regex.Split(line, " "); NOP = Int32.Parse(data[2]); loadPoints = new float[NOP, 2]; Console.WriteLine("---NACTENE BODY ("+NOP+")---"); for (int i = 0, j = 0; j < NOP; i = i + 2, j++) { loadPoints[j, 0] = float.Parse(data[i + 3]); loadPoints[j, 1] = float.Parse(data[i + 4]); Console.WriteLine(""+j+"["+loadPoints[j,0]+"; "+loadPoints[j,1]+"]"); } sr.Close(); } catch (Exception e) { MessageBox.Show("Exception ("+e.Source+"): " + e.Message + "\n"+e.ToString(), "Can not read input file", MessageBoxButtons.OK, MessageBoxIcon.Error); } } /// /// Vypocita rovnomerne rozlozeni bodu. /// Pocet bodu na kruznici. /// public static void PointPlace(int N) { double radius; double fi = 2 * Math.PI / N; double currentFI; points = new float[NOAP, 3]; int k = 0; for (int j = 0; j < NOP; j++) { radius = loadPoints[j, 0]; //polomer je x-ova vzdalenost bodu od pocatku for (int i = 0; i < N; i++) { currentFI = i * fi;//(i + 1) * fi; points[k, 0] = (float)(radius * Math.Sin(currentFI)); points[k, 1] = loadPoints[j, 1]; points[k, 2] = (float)(radius * Math.Cos(currentFI)); k++; //String text = "" + RadianToDegree(actuallyFI) + "° = " + actuallyFI + "\n X = " + x + "(" + pointsX[i] + ")\n Y = " + y + "(" + pointsY[i] + ")"; //MessageBox.Show(text, "Variable Dump", MessageBoxButtons.OK, MessageBoxIcon.Information); } } } public static void CreateTriangles_Blaza() { for (int i = 0, j = 0, k = 0; i < NOAP - NOPOC; i++, j++) { if (j < NOPOC - 1) { triangles[k, 1, 0] = i; triangles[k, 1, 1] = i + NOPOC; triangles[k, 1, 2] = i + NOPOC + 1; k++; triangles[k, 1, 0] = i; triangles[k, 1, 1] = i + NOPOC + 1; triangles[k, 1, 2] = i + 1; k++; } else { triangles[k, 1, 0] = i; triangles[k, 1, 1] = i + NOPOC; triangles[k, 1, 2] = i + 1; k++; triangles[k, 1, 0] = i; triangles[k, 1, 1] = i + 1; triangles[k, 1, 2] = i - (NOPOC - 1); k++; j = -1; //nakonci cyklu se zvýší o 1 a dostane se tím vlastně na nulu } } } public static void CreateTriangles() { Console.WriteLine("Pocet trojuhelniku: " + NOT + "; pocet bodu: " + NOAP + "; bodu na radku: " + NOPOC); // t - číslo aktuálně zpracovávaného trojúhelníku // i - čislo aktuálně zpracovávaného bodu // u - čítač pro uzavření kružnice for (int i = 0, t = 0, u = 0; t < NOT; i++, u++) { if (u < (NOPOC - 1)){ triangles[t, 1, 0] = i; triangles[t, 1, 1] = i + 1; triangles[t, 1, 2] = i + NOPOC; if(t<200)Console.Write("TR č: " + t + " = [" + triangles[t, 1, 0] + "," + triangles[t, 1, 1] + "," + triangles[t, 1, 2] + "] "); t++; triangles[t, 1, 0] = i + NOPOC; triangles[t, 1, 1] = i + 1; triangles[t, 1, 2] = i + NOPOC + 1; if (t < 200) Console.WriteLine("TR č: " + t + " = [" + triangles[t, 1, 0] + "," + triangles[t, 1, 1] + "," + triangles[t, 1, 2] + "] u = "+u); t++; } else { triangles[t, 1, 0] = i; triangles[t, 1, 1] = i - (NOPOC - 1); triangles[t, 1, 2] = i + NOPOC; if (t < 200) Console.Write("TR č: " + t + " = [" + triangles[t, 1, 0] + "," + triangles[t, 1, 1] + "," + triangles[t, 1, 2] + "] "); t++; triangles[t, 1, 0] = i + NOPOC; triangles[t, 1, 1] = i - (NOPOC - 1); triangles[t, 1, 2] = i + 1; if (t < 200) Console.WriteLine("TR č: " + t + " = [" + triangles[t, 1, 0] + "," + triangles[t, 1, 1] + "," + triangles[t, 1, 2] + "] u = "+u); t++; u = -1; //nakonci cyklu se zvýší o 1 a dostane se tím vlastně na nulu } } Console.WriteLine("Počet trojúhelníků: " + NOT); /*Console.WriteLine("---BODY---"); for (int i = 0; i < NOAP; i++) { Console.WriteLine("Bod "+i+" ["+points[i,0]+","+points[i,0]+","+points[i,0]+"]"); }*/ } /// /// Vytvori trojuhelnikovou sit objektu /// public static void CreateTriangles_old() { int q = 0; //aktualni trojuhelnik int a, b, c; //body aktualne vytvareneho trojuhelniku int start, dolni_max, horni_max; for (int offset = 1; offset < NOP; offset++) { start = NOPOC * (offset - 1); dolni_max = (NOPOC + offset) + NOPOC; horni_max = NOPOC * offset; for (int i = start; i < horni_max; i++) { //1. trojuhelnik z bodu i if (q >= NOT) return; a = i % dolni_max; b = (i + NOPOC) % dolni_max; c = (i + NOPOC + 1) % dolni_max; if (c == 0) c = horni_max; triangles[q, 1, 0] = a; triangles[q, 1, 1] = b; triangles[q, 1, 2] = c; q++; //2. trojuhelnik z bodu i if (q >= NOT) return; a = i % dolni_max; b = (i + NOPOC + 1) % dolni_max; if (b == 0) b = horni_max; c = (i + 1) % horni_max; if (c == 0) c = start; triangles[q, 1, 0] = a; triangles[q, 1, 1] = b; triangles[q, 1, 2] = c; q++; } } } /// /// Nastavi vsem trojuhelnikum jejich sousedy /// public static void SetTrianglesNeighbour() { int A, B, C; for (int i = 0; i < NOT; i++) { if (i % 2 == 0) //sude trojuhelniky { A = i + NOTIR + 1; if(A > NOT || A < 0) A = -1; B = i + 1; //odvesna -> ta je bez komplikaci C = (i + NOTIR - 1) % NOTIR; triangles[i, 0, 0] = A; triangles[i, 0, 1] = B; triangles[i, 0, 2] = C; } else //liche trojuhelniky { A = (i + 1) % NOTIR; B = i - (NOTIR + 1); if(B < 0 || B > NOT) B = -1; C = i - 1; //odvesna -> ta je bez komplikaci triangles[i, 0, 0] = A; triangles[i, 0, 1] = B; triangles[i, 0, 2] = C; } } } /// /// Vypocita normalovy vektor trojuhelnika (2 vektorů / 3 bodů) /// public static void GetNormalVectors() { int a, b, c; float[] vectorAB, vectorAC; float x, y, z; vectors = new float[NOT, 3]; for (int i = 0; i < NOT; i++) { //body trojuhelnika a = triangles[i, 1, 0]; b = triangles[i, 1, 1]; c = triangles[i, 1, 2]; //vectory vectorAB = GetVector(a, b); vectorAC = GetVector(a, c); //slozky normaloveho vektoru //vector [x,y,z] // [0,1,2] //vzorec: AB x AC = (ABy * ACz - ABz*ACy; ABz*ACx - ABx*ACz; ABx*ACy - ABy*ACx) x = vectorAB[1] * vectorAC[2] - vectorAB[2] * vectorAC[1]; y = vectorAB[2] * vectorAC[0] - vectorAB[0] * vectorAC[2]; z = vectorAB[0] * vectorAC[1] - vectorAB[1] * vectorAC[0]; //normálový vektor trojúhelníku i vectors[i, 0] = x; vectors[i, 1] = y; vectors[i, 2] = z; } } /// /// Ze dvou bodu vypocita vektor /// public static float[] GetVector(int pointA, int pointB) { pointB = pointB % NOAP; float[] vector = new float[3]; vector[0] = points[pointA, 0] - points[pointB, 0]; //x vector[1] = points[pointA, 1] - points[pointB, 1]; //y vector[2] = points[pointA, 2] - points[pointB, 2]; //z return vector; } public static void SaveOutput(String inname) { String outname = "" + inname + "_out.txt"; new System.IO.StreamWriter(@outname).Close(); //erase the file for first one using (System.IO.StreamWriter file = new System.IO.StreamWriter(@outname, true)) { file.WriteLine(""+NOT); for (int i = 0; i < NOT; i++) { file.WriteLine("" + triangles[i, 0, 0] + " " + triangles[i, 0, 1] + " " + triangles[i, 0, 2] + " " + triangles[i, 1, 0] + " " + triangles[i, 1, 1] + " " + triangles[i, 1, 2]); } file.WriteLine(""+NOAP); for (int i = 0; i < NOAP; i++) { file.WriteLine("" + points[i, 0] + " " + points[i, 1] + " " + points[i, 2]); } } } } }