Reputation: 23
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
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
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