computemachines / scala-physics

Elasticity with Finite Elements
0 stars 0 forks source link

Add geometric primitives and predicates #6

Open computemachines opened 7 years ago

computemachines commented 7 years ago

Issue personal dev log

Point, Segment, Triangle intersectionTest

computemachines commented 7 years ago

I will add these primitives to the rigid subproject. deform will get these primitives through its dependsOn relationship. From build.sbt:

deform.dependsOn(rigid)
computemachines commented 7 years ago

Geometric objects should, where appropriate, behave like numeric types. I want to be able to do:

Point(1, 2) + 0.1*Point(3, 4)
computemachines commented 7 years ago

Better would be:

val point = (1, 2) + 0.1*(3, 4)

Possibilities:

  1. Create new Vector/Point type and use implicit conversions.
    • would still need to pimp Numeric types somehow
      implicit class ScalarOps[U](d: U){
      def *(that: Point): Point = ???
      }
  2. Pimp Tuple2[Double, Double] with vector space methods then pimp numeric types for scalar multiplication.
computemachines commented 7 years ago

Chose possibility (1). Tuple2[T, T] is implicitly converted to my Vector2[T] type with (semiring?) methods. At this moment can:

(1, 2).plus((3, 4)) == (4, 6)

This should work with any numeric type so long as the tuples match Tuple[T, T]. I don't know how to have the compiler automatically promote the types to be equal. This,

(1, 2.0) plus (1, 3)

fails with:

error: could not find implicit value for evidence parameter of type Numeric[AnyVal]

I'm not too worried about this. I will just make sure to use a numeric type uniformly.

computemachines commented 7 years ago

Rewrote past day's work. Tuple2[T : Numeric, T] now 'implements' GeometricVector typeclass. Vector2[T] is an alias for Tuple2[T, T]; I may just remove all references to Vector2 and think only in terms of tuples.

computemachines commented 7 years ago

Finished GeometricVector.Vector2[T]. Now adding common geometric operations like norm, dot product, etc.

computemachines commented 7 years ago

Tests kept taking hours to fail. Solved by using forAllNoShrink instead of forAll. scalacheck doesn't have any logical way of shrinking args that generate floating point rounding errors. Floating point errors are chaotically dependent on the input.

There are lots of details concerning Doubles that I don't understand and really, really don't want to.

computemachines commented 7 years ago

Using scalacheck generators to test properties of Vector2's. Arbitrary.arbitrary[Double] yields Doubles with very extreme exponent. I am writing a reasonableDouble generator with type Arbitrary[Double] to run through my property tests. reasonableDouble will only yield doubles that I expect my vectors to need. +-(0 and 1e-6 to 1e10)

Must remember to add note to api, vectors can only be used if exponent is within a range.

computemachines commented 7 years ago

Testing algebraic properties of Doubles was not a good idea. There are too many ways a precision error can break theorems. I could write a fuzzy equality for doubles but I'd rather just skip testing my vectors. They are simple and fundamental enough that any problems with them will manifest in higher tests.

I will write some geometric tests, then continue with writing geometric data structures and predicates.