Nj15
Nj15

Reputation: 23

scala list LineSegment

I have a polygon consisting of a group of points, I want to find the list of line segments for that polygon by combining the list of corresponding points and then combining the last point with the first one

eg : List of Points - (p1,p2,p3,p4,p5,p6) List of lineSegments - ((p1,p2),(p2,p3),(p3,p4),(p4,p5),(p5,p6),(p6,p1))

sealed trait Shape

case class Point(x: Int, y: Int) extends Shape {
//require(x != null & y !=null, "null values for point")
}

case class LineSegment(point1: Point, point2: Point)  extends Shape {
 require(point1 != point2)

class Group(val children: Shape*) extends Shape {
 require(children != null, "null children in " + getClass.getSimpleName)
 require(!children.contains(null), "null child in " +
 getClass.getSimpleName) }


 object Group {
 def apply(children: Shape*) = new Group(children: _*)
 def unapply(g: Group) = Some(g.children)
 }

 /** A special case of a group consisting only of Points. */
  case class Polygon(override val children: Point*) 
   extends Group(children:   _*){
   require(children != null)

    def findLineSegments(poylgon: Polygon): List[LineSegment] = {
     val points  = children.toList
     val lineSegmentList = points.grouped(2).toList
     return lineSegmentList
    } }

  // polygon example
  val simplePolygon = Polygon(
   Point(50, 50),
   Point(60, 100),
   Point(100, 110),
   Point(120, 60)
   )

I am defining the behaviour findLineSegment to group the corresponding points but what I get is List[list(points)].. how do I convert this list into a list of LineSegments?

Upvotes: 2

Views: 91

Answers (2)

Ben Reich
Ben Reich

Reputation: 16324

You can zip the list with a rotated version of itself and then map to LineSegments:

(points zip ((points drop 1) ::: (points take 1))) map LineSegment.tupled

You might also be interested in the sliding method:

points.sliding(2).map { case List(a, b) => LineSegment(a, b) } 
    :+ LineSegment(points.last, points.head)

Upvotes: 4

Rex Kerr
Rex Kerr

Reputation: 167901

The easiest way is probably as follows.

val rot1 = simplePolygon.drop(1) ++ simplePolygon.take(1)
for ((pi,pj) <- simplePolygon zip rot1) yield LineSegment(pi, pj)

Here, you create a second list shifted by one by dropping one element and adding it back on the end.

Then you traverse both lists at once by zipping them, and at each step associate the two points in a new LineSegment. (It's a case class, so we're actually calling the companion object's apply method here.)

Upvotes: 2

Related Questions