From b1376dff1a375c1371e175817c392f9cbce79377 Mon Sep 17 00:00:00 2001 From: iximeow Date: Wed, 22 Mar 2017 00:59:44 -0700 Subject: partial refactoring to Surface instead of Segment + parabolic lenses --- src/Scene.scala | 88 ++++++++++++++++++++++----------------------------------- 1 file changed, 33 insertions(+), 55 deletions(-) (limited to 'src/Scene.scala') diff --git a/src/Scene.scala b/src/Scene.scala index 9b59f7b..8454f0a 100644 --- a/src/Scene.scala +++ b/src/Scene.scala @@ -6,7 +6,7 @@ import java.awt.image.BufferedImage import javax.imageio._ import java.io.File -case class Scene(walls: Seq[Segment]) { +case class Scene(walls: Seq[Surface]) { val buffer = new BufferedImage(800, 600, BufferedImage.TYPE_INT_RGB) def render(scale: Double = 1, xoff: Int = 0, yoff: Int = 0, color: Int = 0x808000, normals: Boolean = false): Unit = { @@ -14,7 +14,7 @@ case class Scene(walls: Seq[Segment]) { wall.renderTo(buffer, scale, 400, 300, color = color) } for (wall <- walls) { - wall.normal.renderTo(buffer, scale, 400, 300, color = 0xc00000) + wall.normal(0.5).toSegment.renderTo(buffer, scale, 400, 300, color = 0xc00000) } } @@ -32,58 +32,14 @@ case class Scene(walls: Seq[Segment]) { def castSingle(r: Ray): (Ray, Ray) = { val asSeg = r.toSegment - def reflect(firstIntersection: (Segment, Point)): (Ray, Ray) = { - val minAngle = { - val fromStart = Raymath.angleBetween( - r.initial, - firstIntersection._2, - firstIntersection._1.at(0) - ) - val fromEnd = Raymath.angleBetween( - r.initial, - firstIntersection._2, - firstIntersection._1.at(1) - ) - - println("Fromstart: " + Raymath.toDegrees(fromStart)) - println("Fromend: " + Raymath.toDegrees(fromEnd)) - - if (Math.abs(fromStart) < Math.PI / 2) { - fromStart - } else { - fromEnd - } - - fromStart - } - - val maxAngle = Math.PI - minAngle - - val baseAngle = Math.atan2(firstIntersection._1.y, firstIntersection._1.x) - println("base angle: " + Raymath.toDegrees(baseAngle)) - - val reflectedAngle = baseAngle + minAngle - - if (minAngle < 0 || minAngle > Math.PI * 2) { - println("lol") - (r.endingAt(firstIntersection._2), r.endingAt(firstIntersection._2)) //Ray(0, 0, firstIntersection._2)) - } else { - val (x, y) = ( - Math.cos(reflectedAngle) * 3, - Math.sin(reflectedAngle) * 3 - ) - - // Sure hope this is right... - (r.endingAt(firstIntersection._2), Ray(x, y, firstIntersection._2)) - } - } - val intersections: Seq[(Segment, Point)] = walls.flatMap(w => { + val intersections: Seq[(Surface, Point)] = walls.flatMap(w => { w.intersectChecked(asSeg) .map(x => (w, x)) }) - .filter { case (w: Segment, x: Point) => asSeg.tFor(x).map(_ > 0.0000001).getOrElse(false) } + .filter { case (w: Surface, x: Point) => asSeg.tFor(x).map(_ > 0.0000001).getOrElse(false) } - def isBehind(start: Segment, wall: Segment): Boolean = { + /* + def isBehind(start: Segment, wall: Surface): Boolean = { val normal = Ray(-wall.y, wall.x, Point(0, 0)) val rebased = Ray(start.x, start.y, Point(0, 0)) val cosAngle = normal.dot(rebased) / (normal.mag * rebased.mag) @@ -101,27 +57,39 @@ case class Scene(walls: Seq[Segment]) { val otherT = i._1.tFor(i._2) otherT.map(t => t >= 0 && t <= 1 && isBehind(asSeg, i._1)).getOrElse(false) }) + */ - def fnMin(x: (Segment, Point), y: (Segment, Point)) = if (asSeg.tFor(x._2).get < asSeg.tFor(y._2).get) x else y - val firstStop: Option[(Segment, Point)] = stoppedIntersections.reduceOption(fnMin(_, _)) - val firstReflect: Option[(Segment, Point)] = continuedIntersections.reduceOption(fnMin(_, _)) + def fnMin(x: (Surface, Point), y: (Surface, Point)) = if (asSeg.tFor(x._2).get < asSeg.tFor(y._2).get) x else y + /* + val firstStop: Option[(Surface, Point)] = stoppedIntersections.reduceOption(fnMin(_, _)) + val firstReflect: Option[(Surface, Point)] = continuedIntersections.reduceOption(fnMin(_, _)) (firstStop, firstReflect) match { case (None, None) => (r, Ray(r.x, r.y, r.toSegment.at(1))) case (Some(stop), None) => (r.endingAt(stop._2), Ray(0, 0, r.initial)) - case (None, Some(cont)) => reflect(cont)/* reflect */ + case (None, Some(cont)) => cont._1.scatter(r, cont._2) //reflect(cont)// reflect case (Some(stop), Some(cont)) => { if (fnMin(stop, cont) == stop) { (r.endingAt(stop._2), Ray(0, 0, r.initial)) // stop } else { - reflect(cont) + cont._1.scatter(r, cont._2) + //reflect(cont) // reflect } } } + */ + val firstInteraction = intersections +// .map(x => {println("maybe " + x._1); x}) + .filter(i => i._1.tFor(i._2).map(t => t >= 0 && t <= 1).getOrElse(true)) + .reduceOption(fnMin(_, _)) + firstInteraction match { + case None => (r, Ray(r.x, r.y, r.toSegment.at(1))) + case Some(cont) => cont._1.scatter(r, cont._2) + } } } @@ -149,4 +117,14 @@ object Scene { def rotate(walls: Seq[Segment], angle: Double) = walls.map(_.rotate(angle)) + + def rays(number: Int, spacing: Double, centerpoint: Point, direction: Point): Seq[Ray] = { + (0 until number).map { i => + val x = (i.toDouble - number.toDouble / 2) * spacing + val y = 0 + val dx = direction.x + val dy = direction.y + Ray(dx, dy, Point(x, y) + centerpoint) + } + } } -- cgit v1.1