2009-02-13 11 views
7

मैं हाल ही में this raytracer in LINQ पर आया था। बस सोच रहा है कि कोई भी उस पर शीर्ष कर सकता है?आपके द्वारा पारित सबसे प्रभावशाली LINQ कथन क्या है?

var pixelsQuery = 
from y in Enumerable.Range(0, screenHeight) 
let recenterY = -(y - (screenHeight/2.0))/(2.0 * screenHeight) 
select from x in Enumerable.Range(0, screenWidth) 
     let recenterX = (x - (screenWidth/2.0))/(2.0 * screenWidth) 
     let point = Vector.Norm(Vector.Plus(scene.Camera.Forward, 
              Vector.Plus(Vector.Times(recenterX, scene.Camera.Right), 
                 Vector.Times(recenterY, scene.Camera.Up)))) 
     let ray = new Ray { Start = scene.Camera.Pos, Dir = point } 
     let computeTraceRay = (Func<Func<TraceRayArgs, Color>, Func<TraceRayArgs, Color>>) 
     (f => traceRayArgs => 
     (from isect in 
       from thing in traceRayArgs.Scene.Things 
       select thing.Intersect(traceRayArgs.Ray) 
      where isect != null 
      orderby isect.Dist 
      let d = isect.Ray.Dir 
      let pos = Vector.Plus(Vector.Times(isect.Dist, isect.Ray.Dir), isect.Ray.Start) 
      let normal = isect.Thing.Normal(pos) 
      let reflectDir = Vector.Minus(d, Vector.Times(2 * Vector.Dot(normal, d), normal)) 
      let naturalColors = 
       from light in traceRayArgs.Scene.Lights 
       let ldis = Vector.Minus(light.Pos, pos) 
       let livec = Vector.Norm(ldis) 
       let testRay = new Ray { Start = pos, Dir = livec } 
       let testIsects = from inter in 
            from thing in traceRayArgs.Scene.Things 
            select thing.Intersect(testRay) 
           where inter != null 
           orderby inter.Dist 
           select inter 
       let testIsect = testIsects.FirstOrDefault() 
       let neatIsect = testIsect == null ? 0 : testIsect.Dist 
       let isInShadow = !((neatIsect > Vector.Mag(ldis)) || (neatIsect == 0)) 
       where !isInShadow 
       let illum = Vector.Dot(livec, normal) 
       let lcolor = illum > 0 ? Color.Times(illum, light.Color) : Color.Make(0, 0, 0) 
       let specular = Vector.Dot(livec, Vector.Norm(reflectDir)) 
       let scolor = specular > 0 
          ? Color.Times(Math.Pow(specular, isect.Thing.Surface.Roughness), light.Color) 
          : Color.Make(0, 0, 0) 
       select Color.Plus(Color.Times(isect.Thing.Surface.Diffuse(pos), lcolor), 
           Color.Times(isect.Thing.Surface.Specular(pos), scolor)) 
      let reflectPos = Vector.Plus(pos, Vector.Times(.001, reflectDir)) 
      let reflectColor = 
       traceRayArgs.Depth >= MaxDepth 
       ? Color.Make(.5, .5, .5) 
       : Color.Times(isect.Thing.Surface.Reflect(reflectPos), 
          f(new TraceRayArgs(new Ray { Start = reflectPos, Dir = reflectDir }, 
               traceRayArgs.Scene, 
               traceRayArgs.Depth + 1))) 
      select naturalColors.Aggregate(reflectColor, (color, natColor) => Color.Plus(color, natColor))) 
           .DefaultIfEmpty(Color.Background).First()) 
     let traceRay = Y(computeTraceRay) 
     select new { X = x, Y = y, Color = traceRay(new TraceRayArgs(ray, scene, 0)) }; 

foreach (var row in pixelsQuery) 
    foreach (var pixel in row) 
     setPixel(pixel.X, pixel.Y, pixel.Color.ToDrawingColor()); 

उत्तर

6

मुझे शक है raytracer शीर्ष पर कुछ भी उपलब्ध न हो। मैं my Mandelbrot expression हालांकि काफी शौकीन हूँ:

from row in Enumerable.Range(0, ImageHeight) 
from col in Enumerable.Range(0, ImageWidth) 
// Work out the initial complex value from the row and column 
let c = new Complex((col * SampleWidth)/ImageWidth + OffsetX, 
        (row * SampleHeight)/ImageHeight + OffsetY) 
// Work out the number of iterations 
select Generate(c, x => x * x + c).TakeWhile(x => x.SquareLength < 4) 
            .Take(MaxIterations) 
            .Count() into count 
// Map that to an appropriate byte value 
select (byte)(count == MaxIterations ? 0 : (count % 255) + 1); 
2

मुझे पागल कॉल, लेकिन मैं पठनीयता के एक बड़े प्रशंसक हूँ - तो मैं बस व्यक्तिगत रूप से निर्दोष दिखने भाव है कि मैं तो गठबंधन का एक अनुक्रम हो जाते हैं। बेशक, यह निर्भर करता है कि आप LINQ को कैसे परिभाषित करते हैं: यदि आपका मतलब सी # में क्वेरी-सिंटैक्स है, तो मुझे ओवरबोर्ड नहीं जाना पड़ता है ... लेकिन यदि आपका मतलब मेटा प्रोग्रामिंग (यानी सी # कोड है कि एक LINQ अभिव्यक्ति बनाता है)

  • कैसे कुछ object-construction with DbLinq
  • मैं (LINQ) अभिव्यक्ति आधारित गणित दुभाषिया/संकलक है कि मैं Finguistics के लिए लिखा था कहीं आसपास लात मिल गया है के बारे में ...
  • :, मैं कुछ अच्छे उदाहरण मिल गया है
  • generic operators कोड जिसे मैंने MiscUtil के लिए लिखा था, सभी अभिव्यक्ति-आधारित
  • विभिन्न ऑब्जेक्ट पुलिस यिंग उदाहरण (like this)
  • complex OrderBy construction
5

Mads Torgersen demonstrates कैसे LINQ में (उदाहरण के लिए) एक भाज्य एक आत्म निहित पुनरावर्ती लैम्ब्डा अभिव्यक्ति लिखने के लिए गणना करने के लिए:

i => new Func<Func<int,int>,Func<int,int>>(fac => x => x == 0 ? 1 : x * fac(x 
- 1))(new SelfApplicable<Func<Func<Func<int,int>,Func<int,int>>,Func<int,int> 
>>(y => f => x => f(y(y)(f))(x))(y => f => x => f(y(y)(f))(x))(fac => x => x 
== 0 ? 1 : x * fac(x - 1)))(i) 

मैड्स नोट:

मैं यह भी समझ नहीं सकता कि लाइन को कैसे तोड़ना है ताकि यह पठनीय पहुंच सके, इसलिए मैंने नहीं किया है।

+0

आकर्षक (ब्लॉग प्रविष्टि, यानी - लैम्ब्डा स्वयं आंखों में परेशान है ...) –

संबंधित मुद्दे