public void DrawTriangle(double2 [] pts, double3 color, Func <double3, double3, double3> blendFunc = null) { int bottomIdx, midIdx, topIdx, separateIdx, coincidentIdx; Classify3Result res = Math3.Classify3(new [] { pts [0].y, pts [1].y, pts [2].y }, out topIdx, out midIdx, out bottomIdx, out separateIdx, out coincidentIdx); if (res == Classify3Result.AllCoincident) { int x = ( int )Math.Round(pts [0].x, MidpointRounding.AwayFromZero); int y = ( int )Math.Round(pts [0].y, MidpointRounding.AwayFromZero); Values [x, y] = blendFunc == null ? color : blendFunc(Values [x, y], color); return; } else if (res == Classify3Result.HasCoincidence) { double2 separatePoint = pts [separateIdx]; double2 midPoint = pts [midIdx]; double2 coincidentPoint = pts [coincidentIdx]; DrawXAlignedTriangle(separatePoint, midPoint.x, coincidentPoint.x, midPoint.y, color, true, blendFunc); } else { double2 topPoint = pts [topIdx]; double2 midPoint = pts [midIdx]; double2 bottomPoint = pts [bottomIdx]; double dx = topPoint.x - bottomPoint.x; double dy = topPoint.y - bottomPoint.y; double ik = dx / dy; double x2 = ik * (midPoint.y - bottomPoint.y) + bottomPoint.x; DrawXAlignedTriangle(bottomPoint, midPoint.x, x2, midPoint.y, color, true, blendFunc); DrawXAlignedTriangle(topPoint, midPoint.x, x2, midPoint.y, color, false, blendFunc); } }
public static void DrawTexturedTriangle(this HdrBuffer image, double3 [] pts, double2 [] t, Sampler2d sampler, double tpp) { int bottomIdx, midIdx, topIdx, separateIdx, coincidentIdx; Classify3Result res = Math3.Classify3(new [] { pts [0].y, pts [1].y, pts [2].y }, out topIdx, out midIdx, out bottomIdx, out separateIdx, out coincidentIdx); if (res == Classify3Result.AllCoincident) { int x = ( int )Math.Round(pts [0].x, MidpointRounding.AwayFromZero); int y = ( int )Math.Round(pts [0].y, MidpointRounding.AwayFromZero); image.Values [x, y] = sampler.GetColor(t [0]); return; } else if (res == Classify3Result.HasCoincidence) { double3 separatePoint = pts [separateIdx]; double3 midPoint = pts [midIdx]; double3 coincidentPoint = pts [coincidentIdx]; double2 separateT = t [separateIdx]; double2 midT = t [midIdx]; double2 coincidentT = t [coincidentIdx]; image.DrawXAlignedTexturedTriangle(separatePoint, midPoint.x, coincidentPoint.x, midPoint.y, midPoint.z, coincidentPoint.z, separateT, midT, coincidentT, sampler, tpp); //image.DrawXAlignedHollowTriangle ( separatePoint, midPoint.x, coincidentPoint.x, midPoint.y, double3.UnitY ); } else { double3 topPoint = pts [topIdx]; double3 midPoint = pts [midIdx]; double3 bottomPoint = pts [bottomIdx]; double k = (midPoint.y - bottomPoint.y) / (topPoint.y - bottomPoint.y); double x2 = k.Lerp(bottomPoint.x, topPoint.x); double2 topT = t [topIdx]; double2 midT = t [midIdx]; double2 bottomT = t [bottomIdx]; double zInv = k.Lerp(1 / bottomPoint.z, 1 / topPoint.z); double z2 = 1 / zInv; double2 coincidentT = k.ZLerp(bottomT, topT, bottomPoint.z, topPoint.z, zInv); image.DrawXAlignedTexturedTriangle(bottomPoint, midPoint.x, x2, midPoint.y, midPoint.z, z2, bottomT, midT, coincidentT, sampler, tpp); image.DrawXAlignedTexturedTriangle(topPoint, midPoint.x, x2, midPoint.y, midPoint.z, z2, topT, midT, coincidentT, sampler, tpp); //image.DrawXAlignedHollowTriangle ( bottomPoint, midPoint.x, x2, midPoint.y, double3.UnitX ); //image.DrawXAlignedHollowTriangle ( topPoint, midPoint.x, x2, midPoint.y, double3.UnitX ); //double3 white = new double3 ( 1, 1, 1 ); //Func <double3, double3, double3> blendFunc = ( bg, fg ) => bg == white ? double3.UnitX : ( bg == double3.UnitY ? double3.UnitZ : double3.UnitY ); //image.DrawYSteppingLine ( bottomPoint, new double2 ( midPoint.x, midPoint.y ), double3.UnitX, true, false, blendFunc ); //image.DrawYSteppingLine ( bottomPoint, new double2 ( x2, midPoint.y ), double3.UnitX, false, false, blendFunc ); //image.DrawYSteppingLine ( topPoint, new double2 ( midPoint.x, midPoint.y ), double3.UnitX, true, true, blendFunc ); //image.DrawYSteppingLine ( topPoint, new double2 ( x2, midPoint.y ), double3.UnitX, false, true, blendFunc ); } }
public static Classify3Result Classify3 <T> (T [] vals, out int highIdx, out int midIdx, out int lowIdx, out int separateIdx, out int coincidentIdx) where T : IComparable <T> { Classify3Result res = Classify3Result.Distinct; separateIdx = 0; coincidentIdx = 0; int cmp10 = vals [1].CompareTo(vals [0]); int cmp02 = vals [0].CompareTo(vals [2]); if (cmp10 == 1) // 1 > 0 { if (cmp02 == 1) // 1 > 0 > 2 { highIdx = 1; midIdx = 0; lowIdx = 2; } else if (cmp02 == -1) // 1 > 0 < 2 => 1 >= 2 > 0 || 2 > 1 > 0 { lowIdx = 0; int cmp12 = vals [1].CompareTo(vals [2]); if (cmp12 == 0) // 1 == 2 => 1 == 2 > 0 { res = Classify3Result.HasCoincidence; midIdx = 1; highIdx = 1; separateIdx = 0; coincidentIdx = 2; } else if (cmp12 == 1) // 1 > 2 > 0 { midIdx = 2; highIdx = 1; } else /*if ( cmp12 == -1 )*/ // 2 > 1 > 0 { midIdx = 1; highIdx = 2; } } else /*if ( cmp02 == 0 )*/ // 0 == 2 => 1 > 0 == 2 { res = Classify3Result.HasCoincidence; highIdx = 1; midIdx = 0; lowIdx = 0; separateIdx = 1; coincidentIdx = 2; } } else if (cmp10 == -1) // 1 < 0 { if (cmp02 == 1) // 0 > 2 => 1 <= 2 < 0 || 2 < 1 < 0 { highIdx = 0; int cmp12 = vals [1].CompareTo(vals [2]); if (cmp12 == 0) // 1 == 2 => 1 == 2 < 0 { res = Classify3Result.HasCoincidence; midIdx = 1; lowIdx = 1; separateIdx = 0; coincidentIdx = 2; } else if (cmp12 == 1) // 1 > 2 => 2 < 1 < 0 { midIdx = 1; lowIdx = 2; } else /*if ( cmp12 == -1 )*/ // 1 < 2 => 1 < 2 < 0 { midIdx = 2; lowIdx = 1; } } else if (cmp02 == -1) // 0 < 2 => 1 < 0 < 2 { highIdx = 2; midIdx = 0; lowIdx = 1; } else /*if ( cmp02 == 0 )*/ // 0 == 2 => 1 < 0 == 2 { res = Classify3Result.HasCoincidence; highIdx = 0; midIdx = 0; lowIdx = 1; separateIdx = 1; coincidentIdx = 2; } } else /*if ( cmp10 == 0 )*/ // 1 == 0 { res = Classify3Result.HasCoincidence; midIdx = 0; separateIdx = 2; coincidentIdx = 1; int cmp21 = vals [2].CompareTo(vals [1]); if (cmp21 == -1) // 2 < 1 => 2 < 1 == 0 { highIdx = 0; lowIdx = 2; } else if (cmp21 == 1) // 2 > 1 => 2 > 1 == 0 { highIdx = 2; lowIdx = 0; } else /*if ( cmp21 == 0 )*/ // 2 == 0 => 2 == 1 == 0 { res = Classify3Result.AllCoincident; highIdx = 0; lowIdx = 0; } } return(res); }