Welcome to RichStrat, currently showcasing the planets with orbits shown to scale. The other pages use a number of different types of maps.

All the code is written in Scala. When displayed on the web this scala code is compiled to Javascript. However all the demonstations will also compile to Java byte code and work on the JavaFx graphical platfrom. I hope with my modest computing skills to demonstate the power and enjoyment of using Scala for simple games and every day adminstration of personal and small business tasks. At least for the time being I'm not going to give a full introduction to Scala, there are a number of good resources out there, but before I present any code I just want to draw attention to the four common basic types that I use in Scala coding and from which most other types are created.

**Int**: A whole number or integer eg 4, 423, -5, 0**Double**: A fractional number like 5.2, -3.77, 7.0, 0. The name**Double**comes from double precision floating point number. There is also a single precison floating point number called Float, but we will rarely use that so for**Double**you can just think decimal number. A number that could be a whole number, but could have a decimal bit.**String**: Just some text like: "Hello world", "A few more words", "Some more words with other characters like $ % )"**Boolean**: Can be**true**or**false**

Note that 7 is an **Int**. but "7" is a **String**. -8.22 is a **Double**, but "-8.22" is a **String** and **false** is a **Boolean**, but "false" is a **String**. I know this may sound a bit dry, a bit abstract, a bit boring even, but if you can grasp the above you really have cracked the foundations of computer programming. Which is a wonderful thing because now you can get computers to start working for you.

Petyr Baelish, Game of Thrones: *When the Queen proclaims one king and the Hand proclaims another, whose peace do the Computers protect? Who do they follow? The man who programmes them.*

Languages like Basic which you may have come across try to hide these concepts from you, but this leads to no end of trouble down the road for a small time saving at the begining which is why Scala is a way better language than Basic and its ilk. So here's my Vec2 class file. This is the foundation of the map algorithorithms. Note how it contains two data elements, two **Double**s, two decimal values.

` ````
package rich
package geom
import math._
//import rich.geom.Angle
/** A 2 dimensional vector, can be used to represent 2 dimensional points and translations of 2 dimensional points */
class Vec2 (val x: Double, val y: Double) extends PersistCompound
{
override def equals(other: Any): Boolean = other match
{
case Vec2(px, py) => (x =\ px) && (y =\ py)
case _ => false
}
override def toString = "x: " + x.toString + ", y: " + y
def toPair: (Double, Double) = (x, y)
def +(other: Vec2): Vec2 = Vec2(x + other.x, y + other.y)
def plus (otherX: Double, otherY: Double): Vec2 = Vec2(x + otherX, y + otherY)
def minus (otherX: Double, otherY: Double): Vec2 = Vec2(x - otherX, y - otherY)
def -(other: Vec2): Vec2 = Vec2(x - other.x, y - other.y)
def unary_- : Vec2 = Vec2(-x, -y)
def *(factor: Double): Vec2 = Vec2(x * factor, y * factor)
def /(divisor: Double): Vec2 = Vec2(x / divisor, y / divisor)
def addX(adj: Double): Vec2 = Vec2(x + adj, y)
def addY(adj: Double): Vec2 = Vec2(x, y + adj)
def subX(adj: Double): Vec2 = Vec2(x - adj, y)
def subY(adj: Double): Vec2 = Vec2(x, y - adj)
//def commaStr: String = x.toString + ", " + y.toString
override def persistMems: Seq[Persist] = Seq(x, y)
override def persistName: String = "Vec2"
//def persSemi: String = x.toString() -+ y.toString
/* Reverses the y coordinate. Useful for translating between canvases where the y axis measures down and coordinate systems where y is up */
def reverseY: Vec2 = Vec2(x, -y)
def distanceFrom(other: Vec2): Double = math.sqrt({val dim = (x - other.x); dim * dim} + {val dim = (y - other.y); dim * dim})
def rectVerts(width: Double, height: Double): Seq[Vec2] =
{
val ax = width / 2
val ay = height / 2
Seq(Vec2(x - ax, y + ay), Vec2(x + ax, y + ay), Vec2(x + ax, y -ay), Vec2(x -ax, y -ay))
}
def withinRect(target: Vec2, width: Double, height: Double): Boolean =
{
val xd: Double = width / 2
val yd: Double = height / 2
(x > target.x - xd) && (x < target.x + xd) && (y > target.y - yd) && (y < target.y + yd)
}
def rotate(angle: Angle): Vec2 = angle.value match
{
case 0 => Vec2.this
case a => Vec2(x * cos(a) - y * sin(a), x * sin(a) + y * cos(a))
}
//def trans(aff: AffD2): Vec2 = aff(this)
def centreSquare(length: Double): Array[Vec2] =
{
val r = length / 2.0
Array[Vec2](plus(-r, r), plus(r, r), plus(r, -r), plus(-r, -r))
}
}
object Vec2
{
def apply(x: Double, y: Double): Vec2 = new Vec2(x, y)
def unapply(orig: Vec2): Option[(Double, Double)] = Some((orig.x, orig.y))
def zero: Vec2 = new Vec2(0, 0)
def circlePt(angle: Double): Vec2 = Vec2(cos(angle), sin(angle))
def circlePtClockwise(angle: Double): Vec2 = Vec2(cos(angle), - sin(angle))
def gets(coods: Double *): Array[Vec2] =
{
(for ( i <- 0 until coods.length / 2) yield Vec2(coods(i * 2), coods(i * 2 + 1))).toArray
}
def rectBL(left: Double, bottom: Double, width: Double, height: Double): Array[Vec2] =
Array[Vec2](Vec2(left, bottom), Vec2(left, bottom + height), Vec2(left + width, bottom + height), Vec2(left + width, bottom))
def squareBL(left: Double, bottom: Double, length: Double): Array[Vec2] =
Array[Vec2](Vec2(left, bottom), Vec2(left, bottom + length), Vec2(left + length, bottom + length), Vec2(left + length, bottom))
implicit class ImpVec2Array(arr: Array[Vec2])
{
def +++ (offset: Vec2): Array[Vec2] = arr.map(_ + offset)
def xy_+ (xOff: Double, yOff: Double): Array[Vec2] = arr.map(orig => Vec2(orig.x + xOff, orig.y + yOff))
def --- (offset: Vec2): Array[Vec2] = arr.map(_ - offset)
def *** (factor: Double): Array[Vec2] = arr.map(_ * factor)
def a_*+ (factor: Double, offset: Vec2): Array[Vec2] = arr.map(_ * factor + offset)
def a_+* (offset: Vec2, factor: Double): Array[Vec2] = arr.map(i => (i + offset) * factor)
def xy_*+ (factor: Double, xOff: Double, yOff: Double): Array[Vec2] = arr.map(_ * factor + Vec2(xOff, yOff))
def a_+* (xOff: Double, yOff: Double, factor: Double): Array[Vec2] = arr.map(i => (i + Vec2(xOff, yOff)) * factor)
}
import scala.collection.mutable.{ Builder }
import scala.collection._
implicit class ImpVec2Traversible[Repr](travLike: TraversableLike[Vec2, Repr])
{
def +++ (offset: Vec2)(implicit bf: generic.CanBuildFrom[Repr, Vec2, Repr]): Repr =
{
def builder =
{ // extracted to keep method size under 35 bytes, so that it can be JIT-inlined
val b = bf(travLike.repr)
b.sizeHint(travLike)
b
}
val b = builder
for (x <- travLike) b += x + offset
b.result
}
def xy_+ (xOff: Double, yOff: Double)(implicit bf: generic.CanBuildFrom[Repr, Vec2, Repr]): Repr =
{
def builder =
{ // extracted to keep method size under 35 bytes, so that it can be JIT-inlined
val b = bf(travLike.repr)
b.sizeHint(travLike)
b
}
val b = builder
for (orig <- travLike) b += Vec2(orig.x + xOff, orig.y + yOff)
b.result
}
def --- (offset: Vec2)(implicit bf: generic.CanBuildFrom[Repr, Vec2, Repr]): Repr =
{
def builder =
{ // extracted to keep method size under 35 bytes, so that it can be JIT-inlined
val b = bf(travLike.repr)
b.sizeHint(travLike)
b
}
val b = builder
for (x <- travLike) b += x - offset
b.result
}
def *** (factor: Double)(implicit bf: generic.CanBuildFrom[Repr, Vec2, Repr]): Repr =
{
def builder =
{ // extracted to keep method size under 35 bytes, so that it can be JIT-inlined
val b = bf(travLike.repr)
b.sizeHint(travLike)
b
}
val b = builder
for (x <- travLike) b += x * factor
b.result
}
def a_*+ (factor: Double, offset: Vec2)(implicit bf: generic.CanBuildFrom[Repr, Vec2, Repr]): Repr =
{
def builder =
{ // extracted to keep method size under 35 bytes, so that it can be JIT-inlined
val b = bf(travLike.repr)
b.sizeHint(travLike)
b
}
val b = builder
for (x <- travLike) b += x * factor + offset
b.result
}
def a_+* (offset: Vec2, factor: Double)(implicit bf: generic.CanBuildFrom[Repr, Vec2, Repr]): Repr =
{
def builder =
{ // extracted to keep method size under 35 bytes, so that it can be JIT-inlined
val b = bf(travLike.repr)
b.sizeHint(travLike)
b
}
val b = builder
for (x <- travLike) b += (x + offset) * factor
b.result
}
}
implicit object Vec2Persister extends Persister2[Vec2, Double, Double]
{
override def persistType = "Vec2"
override def persister(obj: Vec2): Persist = obj
override def apply = Vec2.apply
}
// def pntInPolygon(verts: Seq[Vec2], pt: Vec2): Boolean =
// { //Checks whether a forward horrisontal ray crosses this polygn side
// val rayIntersections: Seq[Line2] = Line2.SeqFromPts(verts).filter(ls =>
// //Checks whether a forward horrisontal ray crosses this polygn side
// if (
// //Check if point is above or below the polygon side
// ((pt.y > ls.y1) && (pt.y > ls.y2)) || //above pnt1 and pnt2
// ((pt.y < ls.y1) && (pt.y < ls.y2)) //below pnt1 and pnt 2
// ) false
// else
// {
// val deltaY = ls.y2 - ls.y1
// if (0.000001 > deltaY.abs) false //if the polygon side is close to horrisontal the
//// point is close enough to the perimiter of the polygon that the point can measured as outside
// else
// {
// val ptDeltaY = pt.y - ls.y1
// val deltaX = ls.x2 - ls.x1
// val lineX = ls.x1 + (deltaX * ptDeltaY / deltaY)
// pt.x > lineX
// }
// })
// rayIntersections.length.isOdd //For a convex polygon the ray can only cross one side if inside
//}
}
```