1 # This file is part of NIT (http://www.nitlanguage.org).
3 # Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 # Provides interfaces and classes to represent basic geometry needs.
18 module points_and_lines
is serialize
22 # An abstract 2d point, strongly linked to its implementation `Point`
23 interface IPoint[N
: Numeric]
25 # Horizontal coordinate
31 redef fun to_s
do return "({x}, {y})"
33 # Distance with `other`
36 # var p0 = new Point[Float](0.0, 0.0)
37 # var p1 = new Point[Float](2.0, 3.0)
38 # assert p0.dist(p1).is_approx(3.6, 0.01)
41 # TODO 3D implementation.
42 fun dist
(other
: Point[Numeric]): N
44 return x
.value_of
(dist2
(other
).to_f
.sqrt
)
47 # Square of the distance with `other`
49 # May be used as an approximation to compare distance between two points.
52 # var p0 = new Point[Float](0.0, 0.0)
53 # var p1 = new Point[Float](2.0, 3.0)
54 # assert p0.dist2(p1) == 13.0
57 # TODO 3D implementation.
58 fun dist2
(other
: Point[Numeric]): N
60 var dx
= other
.x
.sub
(x
)
61 var dy
= other
.y
.sub
(y
)
62 var s
= (dx
.mul
(dx
)).add
(dy
.mul
(dy
))
66 # Linear interpolation between `self` and `other` at `p` out of `1.0`
69 # var p0 = new Point[Float](0.0, 0.0)
70 # var p1 = new Point[Float](2.0, 3.0)
71 # assert p0.lerp(p1, 0.0) == p0
72 # assert p0.lerp(p1, 1.0) == p1
73 # assert p0.lerp(p1, 0.5) == new Point[Float](1.0, 1.5)
76 # TODO 3D implementation.
77 fun lerp
(other
: Point[Numeric], p
: Float): Point[N
]
79 var xx
= x
.to_f
+ (other
.x
.to_f
- x
.to_f
).to_f
* p
80 var yy
= y
.to_f
+ (other
.y
.to_f
- y
.to_f
).to_f
* p
81 return new Point[N
](x
.value_of
(xx
), y
.value_of
(yy
))
84 redef fun ==(o
) do return o
isa IPoint[Numeric] and o
.x
== x
and o
.y
== y
87 # A 2d point and an implementation of `IPoint`
88 class Point[N
: Numeric]
91 redef var x
: N
is writable
92 redef var y
: N
is writable
95 # An abstract 3d point, strongly linked to its implementation `Point3d`
96 interface IPoint3d[N
: Numeric]
102 redef fun to_s
do return "({x}, {y}, {z})"
105 # A 3d point and an implementation of `IPoint3d`
106 class Point3d[N
: Numeric]
110 redef var z
: N
is writable
113 # An abstract 2d line segment
114 interface ILine[N
: Numeric]
115 # The type of points that ends the segment
118 # The point that is the left-end of the segment
119 fun point_left
: P
is abstract
121 # The point that is the right-end of the segment
122 fun point_right
: P
is abstract
124 redef fun to_s
do return "{point_left}--{point_right}"
128 class Line[N
: Numeric]
132 redef var point_right
145 # An abstract 3d line segment
146 interface ILine3d[N
: Numeric]
149 redef type P
: IPoint3d[N
]
153 class Line3d[N
: Numeric]