public static double[,] lookAt(Vektor pos, Vektor target, Vektor up) { Vektor zaxis = pos - target; zaxis = zaxis.Normalise(); Vektor xaxis = Vektor.CrossProduct(up, zaxis); xaxis = xaxis.Normalise(); Vektor yaxis = Vektor.CrossProduct(zaxis, xaxis); double[,] orientation = { { xaxis.X, yaxis.X, zaxis.X, 0 }, { xaxis.Y, yaxis.Y, zaxis.Y, 0 }, { xaxis.Z, yaxis.Z, zaxis.Z, 0 }, { 0, 0, 0, 1 } }; double[,] translation = { { 1, 0, 0, -pos.X }, { 0, 1, 0, -pos.Y }, { 0, 0, 1, -pos.Z }, { 0, 0, 0, 1 } }; return(Matrix.MultiplyMatrix(orientation, translation)); }
public static Vektor CalcNormals(Vektor v1, Vektor v2) { Vektor v = CrossProduct(v1, v2); v = v.Normalise(); return(new Vektor( x: v.X, y: v.Y, z: v.Z)); }
static Vektor VektorIntersectPlane(Vektor planeP, Vektor planeN, Vektor lineStart, Vektor lineEnd) { planeN = planeN.Normalise(); double planeD = -Vektor.DotProduct(planeN, planeP); double ad = Vektor.DotProduct(lineStart, planeN); double bd = Vektor.DotProduct(lineEnd, planeN); double t = (-planeD - ad) / (bd - ad); Vektor lineStartToEnd = lineEnd - lineStart; Vektor lineToIntersect = lineStartToEnd * new Vektor(t, t, t); return(lineStart + lineToIntersect); }
public static double[,] PointAt(Vektor pos, Vektor target, Vektor up) { Vektor zaxis = pos - target; zaxis = zaxis.Normalise(); Vektor xaxis = Vektor.CrossProduct(up, zaxis); xaxis = xaxis.Normalise(); Vektor yaxis = Vektor.CrossProduct(zaxis, xaxis); double[,] matrix = { { xaxis.X, xaxis.Y, xaxis.Z, pos.X }, { yaxis.X, yaxis.Y, yaxis.Z, pos.Y }, { zaxis.X, zaxis.Y, zaxis.Z, pos.Z }, { 0, 0, 0, 1 } }; return(matrix); }
void Project(Import import, double angle) { List <Vektor> translatedVerts = new List <Vektor>(); List <Triangle> projectedTriangles = new List <Triangle>(); List <Color> projectedTriColor = new List <Color>(); Vektor target = new Vektor(0, 0, 1); double[,] matCameraRotY = Matrix.RotateY(Yaw); double[,] matCameraRotX = Matrix.RotateX(Pitch); _lookDirCamera = Matrix.MultiplyVektor(matCameraRotY, target); target = _camera + _lookDirCamera; double[,] matView = Matrix.lookAt(_camera, target, _up); for (int j = 0; j < import.Verts.Count; j++) { Vektor element = import.Verts[j]; Vektor erg = Matrix.MultiplyVektor(Matrix.WorldMatrix(new Vektor(angle, angle, angle), new Vektor(0, 0, abstand)), element); translatedVerts.Add(erg); } List <Triangle> sortedTriangles = new List <Triangle>(); List <Triangle> sortedTrianglesF = new List <Triangle>(); Dictionary <Triangle, double> sort = new Dictionary <Triangle, double>(); foreach (var triangle in import.CreateTriangles(translatedVerts)) { sort.Add(triangle, triangle.Tp1.Z + triangle.Tp2.Z + triangle.Tp3.Z / 3); } foreach (KeyValuePair <Triangle, double> author in sort.OrderBy(key => key.Value)) { sortedTriangles.Add(author.Key); } for (int t = 0; t < sortedTriangles.Count; t++) { sortedTrianglesF.Add(sortedTriangles[sortedTriangles.Count - 1 - t]); } foreach (var triangle in sortedTrianglesF) { Vektor line1 = new Vektor(triangle.Tp2, triangle.Tp1); Vektor line2 = new Vektor(triangle.Tp2, triangle.Tp3); Vektor normal = Vektor.CalcNormals(line1, line2); Vektor pointToCamera = _camera - triangle.Tp1; if (Vektor.DotProduct(pointToCamera, normal) < 0) { Vektor lightDirection = _camera + new Vektor(0, 0, -1); lightDirection = lightDirection.Normalise(); double dp = Vektor.DotProduct(normal, lightDirection); var grayValue = Convert.ToByte(Math.Abs(dp * Byte.MaxValue)); var col = Color.FromArgb(250, grayValue, grayValue, grayValue); var tp1 = Matrix.MultiplyVektor(matView, triangle.Tp1); var tp2 = Matrix.MultiplyVektor(matView, triangle.Tp2); var tp3 = Matrix.MultiplyVektor(matView, triangle.Tp3); Triangle triViewed = new Triangle(tp1, tp2, tp3); int clippedTriangles = 0; Triangle[] clipped = new Triangle[4]; clippedTriangles += Clipping.Triangle_ClipAgainstPlane(new Vektor(0, 0, -near), new Vektor(0, 0, -1), triViewed); clipped[0] = Clipping.outTri1; clipped[1] = Clipping.outTri2; for (int n = 0; n < clippedTriangles; n++) { Vektor projectedPoint1 = PerspectiveProjectionMatrix(clipped[n].Tp1); Vektor projectedPoint2 = PerspectiveProjectionMatrix(clipped[n].Tp2); Vektor projectedPoint3 = PerspectiveProjectionMatrix(clipped[n].Tp3); projectedTriangles.Add(new Triangle(projectedPoint1, projectedPoint2, projectedPoint3)); projectedTriColor.Add(col); } } } foreach (Triangle triToRaster in projectedTriangles) { int c = 0; Triangle[] clipped = new Triangle[2]; List <Triangle> listTriangles = new List <Triangle>(); Color col = projectedTriColor[c]; listTriangles.Add(triToRaster); int newTriangles = 1; for (int p = 0; p < 4; p++) { int TrisToAdd = 0; while (newTriangles > 0) { Triangle test = listTriangles[0]; listTriangles.RemoveAt(0); newTriangles--; switch (p) { case 0: TrisToAdd = Clipping.Triangle_ClipAgainstPlane(new Vektor(0, (-_drawingSurface.Surface.ActualHeight / 2) / 50, 0), new Vektor(0, 1, 0), test); clipped[0] = Clipping.outTri1; clipped[1] = Clipping.outTri2; break; case 1: TrisToAdd = Clipping.Triangle_ClipAgainstPlane(new Vektor(0, (_drawingSurface.Surface.ActualHeight / 2) / 50, 0), new Vektor(0, -1, 0), test); clipped[0] = Clipping.outTri1; clipped[1] = Clipping.outTri2; break; case 2: TrisToAdd = Clipping.Triangle_ClipAgainstPlane(new Vektor((-_drawingSurface.Surface.ActualWidth / 2) / 50, 0, 0), new Vektor(1, 0, 0), test); clipped[0] = Clipping.outTri1; clipped[1] = Clipping.outTri2; break; case 3: TrisToAdd = Clipping.Triangle_ClipAgainstPlane(new Vektor((_drawingSurface.Surface.ActualWidth / 2) / 50, 0, 0), new Vektor(-1, 0, 0), test); clipped[0] = Clipping.outTri1; clipped[1] = Clipping.outTri2; break; } for (int w = 0; w < TrisToAdd; w++) { listTriangles.Add(clipped[w]); } } newTriangles = listTriangles.Count; } for (int i = 0; i < listTriangles.Count; i++) { _drawingSurface.Triangle(listTriangles[i], col); } c++; } }
public static int Triangle_ClipAgainstPlane(Vektor planeP, Vektor planeN, Triangle inTri) { outTri1 = new Triangle(); outTri2 = new Triangle(); planeN = planeN.Normalise(); Vektor[] insidePoints = new Vektor[3]; Vektor[] outsidePoints = new Vektor[3]; int InsidePointCount = 0; int OutsidePointCount = 0; double d0 = calcdis(inTri.Tp1, planeP, planeN); double d1 = calcdis(inTri.Tp2, planeP, planeN); double d2 = calcdis(inTri.Tp3, planeP, planeN); if (d0 > 0) { insidePoints[InsidePointCount++] = inTri.Tp1; } else { outsidePoints[OutsidePointCount++] = inTri.Tp1; } if (d1 > 0) { insidePoints[InsidePointCount++] = inTri.Tp2; } else { outsidePoints[OutsidePointCount++] = inTri.Tp2; } if (d2 > 0) { insidePoints[InsidePointCount++] = inTri.Tp3; } else { outsidePoints[OutsidePointCount++] = inTri.Tp3; } if (InsidePointCount == 0) { return(0); } if (InsidePointCount == 3) { outTri1 = inTri; return(1); } if (InsidePointCount == 1 && OutsidePointCount == 2) { outTri1.Tp1 = insidePoints[0]; outTri1.Tp2 = VektorIntersectPlane(planeP, planeN, insidePoints[0], outsidePoints[0]); outTri1.Tp3 = VektorIntersectPlane(planeP, planeN, insidePoints[0], outsidePoints[1]); return(1); } if (InsidePointCount == 2 && OutsidePointCount == 1) { outTri1.Tp1 = insidePoints[0]; outTri1.Tp2 = insidePoints[1]; outTri1.Tp3 = VektorIntersectPlane(planeP, planeN, insidePoints[0], outsidePoints[0]); outTri2.Tp1 = insidePoints[1]; outTri2.Tp2 = outTri1.Tp3; outTri2.Tp3 = VektorIntersectPlane(planeP, planeN, insidePoints[1], outsidePoints[0]); return(2); } return(1); }