Code Sketch


3D plan: Initial attempt
By: Anay Narendra Kamat
Category: Programming
cleari

case class Vector3D(x:Double, y:Double, z:Double)

def viewAngleHalf = Math.toRadians(90.0/2.0)

def size = canvasBounds.width*0.5

def face = Seq(
        Vector3D(-100,-100,size),
        Vector3D(100,-100,size),
        Vector3D(100,-100,size+200),
        Vector3D(-100,-100,size+200),
        Vector3D(-100,-100,size),
    )

def translateToOrigin(referencePoint:Vector3D,point:Vector3D):Vector3D = 
        Vector3D(
                point.x - referencePoint.x,
                point.y - referencePoint.y,
                point.z - referencePoint.z,
            )

def translateBy(referencePoint:Vector3D,point:Vector3D):Vector3D = 
        Vector3D(
                point.x + referencePoint.x,
                point.y + referencePoint.y,
                point.z + referencePoint.z,
            )

def rotateAroundY(angle:Double,point:Vector3D) = 
    Vector3D(
            point.x*Math.cos(angle)+point.z*Math.sin(angle),
            point.y,
            point.z*Math.cos(angle)-point.x*Math.sin(angle),
        )


def normalisePoint(point:Vector3D):Vector3D={   
    return Vector3D(
            point.x/(canvasBounds.width*0.5),
            point.y/(canvasBounds.width*0.5),
            point.z/(canvasBounds.width*0.5)
        )
}

def toWorld(point:Vector3D):Vector3D={   
    return Vector3D(
            point.x*(canvasBounds.width*0.5),
            point.y*(canvasBounds.width*0.5),
            point.z*canvasBounds.width*0.5
        )
}

def toPerspective(point:Vector3D):Vector3D={
    return Vector3D(
            point.x/(point.z*Math.tan(viewAngleHalf)),
            point.y/(point.z*Math.tan(viewAngleHalf)),
            point.z
        )
}



def drawFace(face:Seq[Vector3D]):Picture = Picture.fromVertexShape { x =>
    x.beginShape()
    face.foreach { v =>
        x.vertex(v.x, v.y) 
    }
    x.endShape()
}

def color = cm.linearGradient(0, -200, red, 0, 100, black, false)


animateWithState(0) { angle =>

    erasePictures()
    
    val transformedFace = 
        face
        .map(translateToOrigin(Vector3D(0,0,size+100),_))
        .map(rotateAroundY(Math.toRadians(angle),_))
        .map(translateBy(Vector3D(0,0,size+100),_))
        .map(normalisePoint) 
        .map(toPerspective)    
        .map(toWorld) 
    draw(drawFace(transformedFace).thatsFilledWith(color).thatsStrokeColored(noColor))    

    angle+1
    
}

setBackground(black)