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()
{
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);
}
///
/// 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]);
}
}
}
}
}