Geometric Vector collections

Rich Oliver <[email protected]> Tue, 20 Dec 2016 08:07:46 -0800 (PST)
Newsgroups gmane.comp.lang.scala
Message-ID <[email protected]>
------=_Part_434_643207614.1482250066397
Content-Type: multipart/alternative; 
	boundary="----=_Part_435_129540147.1482250066397"

------=_Part_435_129540147.1482250066397
Content-Type: text/plain; charset=UTF-8

A substantial amount of my code base uses 2 dimensional vectors. Pretty 
standard stuff, that hopefully will one day be included in the standard 
library:

final 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
   }
   def +(other: Vec2): Vec2 = Vec2(x + other.x, y + other.y)
...........
}

I'm currently using an implicit class to add methods:

object Vec2
{
   /** Translates each Vec2 member of collection equivalent to trav.map(_ + 
offset) */
      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
      } 

   /** Creates a bounding rectangle for a collection of 2d points */
      def boundingRect: BoundingRect =
      {
         var minX, maxX, minY, maxY = 0.0
         var i = 0
         for (v <- travLike)
         {
            if (i == 0)
            {
               minX = v.x
               maxX = v.x
               minY = v.y
               maxY = v.y
            }
            else
            {
               minX = minX.min(v.x)
               maxX = maxX.max(v.x)
               minY = minY.min(v.y)
               maxY = maxY.max(v.y)
            }
            i += 1
         }
         if (i == 0) throw new Exception("boundingRect method called on 
empty Vec2 collection") else {}
         BoundingRect(minX, maxX, minY, maxY)               
      }   
   ....................
   }
 } 

*1* Pretty horrible code. So my first question is: are those the correct 
ways to write those methods in 2.12 using the implicits if I want them to 
be efficient?

*2* Should there be an inline annotation on the + method of the Vec2 class?

*3* However I'm now wondering if I should use a custom collection class and 
then just create the methods directly on the class and always use the 
custom type where I currently have Seq[Vec2]. The two obvious 
implementation strategies are a wrapped Array or a custom List class with 
custom Cons and Nil classes. I'm leaning towards the latter as most of my 
Vec2 collections are small and it makes, building and iterating with 
immutability straight forward.

*4*  The 2d, 3d and 4d Vectors strike me as very important classes. The 3d 
Vector is given as the canonical example of a struct in Scala Native. So I 
wondered how the thinking for the new collections library in 2.13 will 
effect these classes?

*5* Will we be able to use Scala Native Vector Structs while still 
maintaining a largely common code base for ScalaJvm and ScalaJs? This seems 
to me completely entangled with the question of collections.

-- 
You received this message because you are subscribed to the Google Groups "scala-language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.

------=_Part_435_129540147.1482250066397
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: base64

PGRpdiBkaXI9Imx0ciI+QSBzdWJzdGFudGlhbCBhbW91bnQgb2YgbXkgY29kZSBiYXNlIHVzZXMg
MiBkaW1lbnNpb25hbCB2ZWN0b3JzLiBQcmV0dHkgc3RhbmRhcmQgc3R1ZmYsIHRoYXQgaG9wZWZ1
bGx5IHdpbGwgb25lIGRheSBiZSBpbmNsdWRlZCBpbiB0aGUgc3RhbmRhcmQgbGlicmFyeTo8YnI+
PGJyPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDAsIDAsIDI1NSk7Ij5maW5hbCBjbGFzcyBWZWMy
ICh2YWwgeDogRG91YmxlLCB2YWwgeTogRG91YmxlKSBleHRlbmRzIFBlcnNpc3RDb21wb3VuZDxi
cj57PGJyPsKgwqAgb3ZlcnJpZGUgZGVmIGVxdWFscyhvdGhlcjogQW55KTogQm9vbGVhbiA9IG90
aGVyIG1hdGNoPGJyPsKgwqAgezxicj7CoMKgwqDCoMKgIGNhc2UgVmVjMihweCwgcHkpID0mZ3Q7
ICh4ID1cIHB4KSAmYW1wOyZhbXA7ICh5ID1cIHB5KTxicj7CoMKgwqDCoMKgIGNhc2UgXyA9Jmd0
OyBmYWxzZTxicj7CoMKgIH08YnI+wqDCoCBkZWYgKyhvdGhlcjogVmVjMik6IFZlYzIgPSBWZWMy
KHggKyBvdGhlci54LCB5ICsgb3RoZXIueSk8YnI+Li4uLi4uLi4uLi48YnI+fTwvc3Bhbj48YnI+
PGJyPkkmIzM5O20gY3VycmVudGx5IHVzaW5nIGFuIGltcGxpY2l0IGNsYXNzIHRvIGFkZCBtZXRo
b2RzOjxicj48YnI+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMjU1KTsiPm9iamVjdCBW
ZWMyPGJyPns8YnI+wqDCoCAvKiogVHJhbnNsYXRlcyBlYWNoIFZlYzIgbWVtYmVyIG9mIGNvbGxl
Y3Rpb24gZXF1aXZhbGVudCB0byB0cmF2Lm1hcChfICsgb2Zmc2V0KSAqLzxicj7CoMKgwqDCoMKg
IGRlZiArKysgKG9mZnNldDogVmVjMikoaW1wbGljaXQgYmY6IGdlbmVyaWMuQ2FuQnVpbGRGcm9t
W1JlcHIsIFZlYzIsIFJlcHJdKTogUmVwciA9PGJyPsKgwqDCoMKgwqAgezxicj7CoMKgwqDCoMKg
wqDCoMKgIGRlZiBidWlsZGVyID08YnI+wqDCoMKgwqDCoMKgwqDCoCB7IC8vIGV4dHJhY3RlZCB0
byBrZWVwIG1ldGhvZCBzaXplIHVuZGVyIDM1IGJ5dGVzLCBzbyB0aGF0IGl0IGNhbiBiZSBKSVQt
aW5saW5lZDxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHZhbCBiID0gYmYodHJhdkxpa2UucmVw
cik8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBiLnNpemVIaW50KHRyYXZMaWtlKTxicj7CoMKg
wqDCoMKgwqDCoMKgwqDCoMKgIGI8YnI+wqDCoMKgwqDCoMKgwqDCoCB9PGJyPsKgwqDCoMKgwqDC
oMKgwqAgdmFsIGIgPSBidWlsZGVyPGJyPsKgwqDCoMKgwqDCoMKgwqAgZm9yICh4ICZsdDstIHRy
YXZMaWtlKSBiICs9IHggKyBvZmZzZXQ8YnI+wqDCoMKgwqDCoMKgwqDCoCBiLnJlc3VsdDxicj7C
oMKgwqDCoMKgIH0gPGJyPjxicj7CoMKgIC8qKiBDcmVhdGVzIGEgYm91bmRpbmcgcmVjdGFuZ2xl
IGZvciBhIGNvbGxlY3Rpb24gb2YgMmQgcG9pbnRzICovPGJyPsKgwqDCoMKgwqAgZGVmIGJvdW5k
aW5nUmVjdDogQm91bmRpbmdSZWN0ID08YnI+wqDCoMKgwqDCoCB7PGJyPsKgwqDCoMKgwqDCoMKg
wqAgdmFyIG1pblgsIG1heFgsIG1pblksIG1heFkgPSAwLjA8YnI+wqDCoMKgwqDCoMKgwqDCoCB2
YXIgaSA9IDA8YnI+wqDCoMKgwqDCoMKgwqDCoCBmb3IgKHYgJmx0Oy0gdHJhdkxpa2UpPGJyPsKg
wqDCoMKgwqDCoMKgwqAgezxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGlmIChpID09IDApPGJy
PsKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgezxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg
IG1pblggPSB2Lng8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBtYXhYID0gdi54PGJy
PsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgbWluWSA9IHYueTxicj7CoMKgwqDCoMKgwqDC
oMKgwqDCoMKgwqDCoMKgIG1heFkgPSB2Lnk8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB9PGJy
PsKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgZWxzZTxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHs8
YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBtaW5YID0gbWluWC5taW4odi54KTxicj7C
oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIG1heFggPSBtYXhYLm1heCh2LngpPGJyPsKgwqDC
oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgbWluWSA9IG1pblkubWluKHYueSk8YnI+wqDCoMKgwqDC
oMKgwqDCoMKgwqDCoMKgwqDCoCBtYXhZID0gbWF4WS5tYXgodi55KTxicj7CoMKgwqDCoMKgwqDC
oMKgwqDCoMKgIH08YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBpICs9IDE8YnI+wqDCoMKgwqDC
oMKgwqDCoCB9PGJyPsKgwqDCoMKgwqDCoMKgwqAgaWYgKGkgPT0gMCkgdGhyb3cgbmV3IEV4Y2Vw
dGlvbigmcXVvdDtib3VuZGluZ1JlY3QgbWV0aG9kIGNhbGxlZCBvbiBlbXB0eSBWZWMyIGNvbGxl
Y3Rpb24mcXVvdDspIGVsc2Uge308YnI+wqDCoMKgwqDCoMKgwqDCoCBCb3VuZGluZ1JlY3QobWlu
WCwgbWF4WCwgbWluWSwgbWF4WSnCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDxicj7CoMKg
wqDCoMKgIH3CoMKgIDxicj7CoMKgIC4uLi4uLi4uLi4uLi4uLi4uLi4uPGJyPsKgwqAgfTxicj7C
oH0gPC9zcGFuPjxicj48YnI+PGI+MTwvYj4gUHJldHR5IGhvcnJpYmxlIGNvZGUuIFNvIG15IGZp
cnN0IHF1ZXN0aW9uIGlzOiBhcmUgdGhvc2UgdGhlIGNvcnJlY3Qgd2F5cyB0byB3cml0ZSB0aG9z
ZSBtZXRob2RzIGluIDIuMTIgdXNpbmcgdGhlIGltcGxpY2l0cyBpZiBJIHdhbnQgdGhlbSB0byBi
ZSBlZmZpY2llbnQ/PGJyPjxicj48Yj4yPC9iPiBTaG91bGQgdGhlcmUgYmUgYW4gaW5saW5lIGFu
bm90YXRpb24gb24gdGhlICsgbWV0aG9kIG9mIHRoZSBWZWMyIGNsYXNzPzxicj48YnI+PGI+Mzwv
Yj4gSG93ZXZlciBJJiMzOTttIG5vdyB3b25kZXJpbmcgaWYgSSBzaG91bGQgdXNlIGEgY3VzdG9t
IGNvbGxlY3Rpb24gY2xhc3MgYW5kIHRoZW4ganVzdCBjcmVhdGUgdGhlIG1ldGhvZHMgZGlyZWN0
bHkgb24gdGhlIGNsYXNzIGFuZCBhbHdheXMgdXNlIHRoZSBjdXN0b20gdHlwZSB3aGVyZSBJIGN1
cnJlbnRseSBoYXZlIFNlcVtWZWMyXS4gVGhlIHR3byBvYnZpb3VzIGltcGxlbWVudGF0aW9uIHN0
cmF0ZWdpZXMgYXJlIGEgd3JhcHBlZCBBcnJheSBvciBhIGN1c3RvbSBMaXN0IGNsYXNzIHdpdGgg
Y3VzdG9tIENvbnMgYW5kIE5pbCBjbGFzc2VzLiBJJiMzOTttIGxlYW5pbmcgdG93YXJkcyB0aGUg
bGF0dGVyIGFzIG1vc3Qgb2YgbXkgVmVjMiBjb2xsZWN0aW9ucyBhcmUgc21hbGwgYW5kIGl0IG1h
a2VzLCBidWlsZGluZyBhbmQgaXRlcmF0aW5nIHdpdGggaW1tdXRhYmlsaXR5IHN0cmFpZ2h0IGZv
cndhcmQuPGJyPjxicj48Yj40PC9iPsKgIFRoZSAyZCwgM2QgYW5kIDRkIFZlY3RvcnMgc3RyaWtl
IG1lIGFzIHZlcnkgaW1wb3J0YW50IGNsYXNzZXMuIFRoZSAzZCBWZWN0b3IgaXMgZ2l2ZW4gYXMg
dGhlIGNhbm9uaWNhbCBleGFtcGxlIG9mIGEgc3RydWN0IGluIFNjYWxhIE5hdGl2ZS4gU28gSSB3
b25kZXJlZCBob3cgdGhlIHRoaW5raW5nIGZvciB0aGUgbmV3IGNvbGxlY3Rpb25zIGxpYnJhcnkg
aW4gMi4xMyB3aWxsIGVmZmVjdCB0aGVzZSBjbGFzc2VzPzxicj48YnI+PGI+NTwvYj4gV2lsbCB3
ZSBiZSBhYmxlIHRvIHVzZSBTY2FsYSBOYXRpdmUgVmVjdG9yIFN0cnVjdHMgd2hpbGUgc3RpbGwg
bWFpbnRhaW5pbmcgYSBsYXJnZWx5IGNvbW1vbiBjb2RlIGJhc2UgZm9yIFNjYWxhSnZtIGFuZCBT
Y2FsYUpzPyBUaGlzIHNlZW1zIHRvIG1lIGNvbXBsZXRlbHkgZW50YW5nbGVkIHdpdGggdGhlIHF1
ZXN0aW9uIG9mIGNvbGxlY3Rpb25zLjxicj48L2Rpdj4NCg0KPHA+PC9wPgoKLS0gPGJyIC8+Cllv
dSByZWNlaXZlZCB0aGlzIG1lc3NhZ2UgYmVjYXVzZSB5b3UgYXJlIHN1YnNjcmliZWQgdG8gdGhl
IEdvb2dsZSBHcm91cHMgJnF1b3Q7c2NhbGEtbGFuZ3VhZ2UmcXVvdDsgZ3JvdXAuPGJyIC8+ClRv
IHVuc3Vic2NyaWJlIGZyb20gdGhpcyBncm91cCBhbmQgc3RvcCByZWNlaXZpbmcgZW1haWxzIGZy
b20gaXQsIHNlbmQgYW4gZW1haWwgdG8gPGEgaHJlZj0ibWFpbHRvOnNjYWxhLWxhbmd1YWdlK3Vu
c3Vic2NyaWJlQGdvb2dsZWdyb3Vwcy5jb20iPnNjYWxhLWxhbmd1YWdlK3Vuc3Vic2NyaWJlQGdv
b2dsZWdyb3Vwcy5jb208L2E+LjxiciAvPgpGb3IgbW9yZSBvcHRpb25zLCB2aXNpdCA8YSBocmVm
PSJodHRwczovL2dyb3Vwcy5nb29nbGUuY29tL2Qvb3B0b3V0Ij5odHRwczovL2dyb3Vwcy5nb29n
bGUuY29tL2Qvb3B0b3V0PC9hPi48YnIgLz4K
------=_Part_435_129540147.1482250066397--

------=_Part_434_643207614.1482250066397--