From: Alexis Laferrière Date: Sun, 7 Jan 2018 14:26:50 +0000 (-0500) Subject: examples: delete mnit_ballz X-Git-Url: http://nitlanguage.org examples: delete mnit_ballz Signed-off-by: Alexis Laferrière --- diff --git a/examples/mnit_ballz/Makefile b/examples/mnit_ballz/Makefile deleted file mode 100644 index f42e903..0000000 --- a/examples/mnit_ballz/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -default: linux - -../../contrib/inkscape_tools/bin/svg_to_icons: - $(MAKE) -C ../../contrib/inkscape_tools - -android: icon - mkdir -p bin - ../../bin/nitc -o bin/ballz.apk src/ballz_android.nit - -android-release: icon - mkdir -p bin - ../../bin/nitc -o bin/ballz.apk src/ballz_android.nit --release - -linux: - mkdir -p bin - ../../bin/nitc -o bin/ballz src/ballz_linux.nit - -icon: ../../contrib/inkscape_tools/bin/svg_to_icons - mkdir -p android/res - ../../contrib/inkscape_tools/bin/svg_to_icons art/ball.svg --android --out android/res/ - -clean: - rm -rf bin android diff --git a/examples/mnit_ballz/art/ball.svg b/examples/mnit_ballz/art/ball.svg deleted file mode 100644 index ada039c..0000000 --- a/examples/mnit_ballz/art/ball.svg +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - diff --git a/examples/mnit_ballz/assets/images/ball.png b/examples/mnit_ballz/assets/images/ball.png deleted file mode 100644 index 0f92733..0000000 Binary files a/examples/mnit_ballz/assets/images/ball.png and /dev/null differ diff --git a/examples/mnit_ballz/assets/images/horizontal_wall.png b/examples/mnit_ballz/assets/images/horizontal_wall.png deleted file mode 100644 index 7ba6c68..0000000 Binary files a/examples/mnit_ballz/assets/images/horizontal_wall.png and /dev/null differ diff --git a/examples/mnit_ballz/assets/images/vertical_wall.png b/examples/mnit_ballz/assets/images/vertical_wall.png deleted file mode 100644 index da42302..0000000 Binary files a/examples/mnit_ballz/assets/images/vertical_wall.png and /dev/null differ diff --git a/examples/mnit_ballz/org.nitlanguage.ballz.txt b/examples/mnit_ballz/org.nitlanguage.ballz.txt deleted file mode 100644 index c7a110a..0000000 --- a/examples/mnit_ballz/org.nitlanguage.ballz.txt +++ /dev/null @@ -1,11 +0,0 @@ -Categories:Nit -License:Apache2 -Web Site:http://nitlanguage.org -Source Code:http://nitlanguage.org/nit.git/tree/HEAD:/examples/mnit_ballz -Issue Tracker:https://github.com/nitlang/nit/issues - -Summary:A Sensor Demo -Description: -Demonstration of the mnit+android sensor API. -Control a ball with tap, tilt, obscur, etc. -. diff --git a/examples/mnit_ballz/package.ini b/examples/mnit_ballz/package.ini deleted file mode 100644 index 9db4745..0000000 --- a/examples/mnit_ballz/package.ini +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name=mnit_ballz -tags=game -maintainer=Romain Chanoir -license=Apache-2.0 -[upstream] -browse=https://github.com/nitlang/nit/tree/master/examples/mnit_ballz/ -git=https://github.com/nitlang/nit.git -git.directory=examples/mnit_ballz/ -homepage=http://nitlanguage.org -issues=https://github.com/nitlang/nit/issues -apk=http://nitlanguage.org/fdroid/apk/ballz.apk diff --git a/examples/mnit_ballz/res/raw/bounce.ogg b/examples/mnit_ballz/res/raw/bounce.ogg deleted file mode 100644 index bcd66dd..0000000 Binary files a/examples/mnit_ballz/res/raw/bounce.ogg and /dev/null differ diff --git a/examples/mnit_ballz/res/raw/walld.wav b/examples/mnit_ballz/res/raw/walld.wav deleted file mode 100644 index f61d065..0000000 Binary files a/examples/mnit_ballz/res/raw/walld.wav and /dev/null differ diff --git a/examples/mnit_ballz/src/assets.nit b/examples/mnit_ballz/src/assets.nit deleted file mode 100644 index e823284..0000000 --- a/examples/mnit_ballz/src/assets.nit +++ /dev/null @@ -1,49 +0,0 @@ -# this file is part of NIT ( http://www.nitlanguage.org ). -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -# All the assets needed by the appplication, regrouped in one class -module assets - -import app::audio -import mnit::assets - - -# Contains all the assets -class Assets - - # Sound for the wall destruction - var wall_destruction = new Sound("walld.wav") - - # Sound when the ball bounce - var bounce = new Sound("bounce.ogg") - - # Image of the ball - var ball: Image is noinit - - # Image for the horizontal walls - var horizontal_wall: Image is noinit - - # Image for the vertical walls - var vertical_wall: Image is noinit - - # Loads all the assets - fun load do - ball = app.load_image("images/ball.png") - horizontal_wall = app.load_image("images/horizontal_wall.png") - vertical_wall = app.load_image("images/vertical_wall.png") - wall_destruction.load - bounce.load - end -end diff --git a/examples/mnit_ballz/src/ballz_android.nit b/examples/mnit_ballz/src/ballz_android.nit deleted file mode 100644 index ee41e9c..0000000 --- a/examples/mnit_ballz/src/ballz_android.nit +++ /dev/null @@ -1,112 +0,0 @@ -# this file is part of NIT ( http://www.nitlanguage.org ). -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -# Android part of mnit_ballz -module ballz_android is - app_version(0, 2, git_revision) - app_name("Ballz") - app_namespace "org.nitlanguage.ballz" - android_api_target 19 -end - -import android::portrait -import android::sensors -import display -import mnit::android - -redef class App - - # The game - var game: nullable Game is noautoinit - - redef fun run do - accelerometer.enabled = true - accelerometer.event_rate = 10000 - magnetic_field.enabled = true - gyroscope.enabled = true - light.enabled = true - proximity.enabled = true - maximum_fps = 50.0 - sensors_support_enabled = true - super - end - - redef fun on_create - do - super - var display = self.display.as(not null) - game = new Game(display.width.to_f, display.height.to_f) - end - - redef fun frame_core(display) - do - var game = game - if game != null then - game.do_turn - game.draw(display, assets) - end - end - - redef fun input(ie) - do - if paused then return false - if ie isa QuitEvent then - quit = true - return true - end - var game = game - if game != null then - return game.input(ie) - end - return false - end -end - -redef class Ball - - redef fun intercepts(event) - do - if event isa ASensorAccelerometer then - acceleration(event.x, event.y) - else if event isa ASensorMagneticField then - #deal with Magnetic field sensor - #print "ASensorMagneticField : x = " + event.x.to_s + " y = " + event.y.to_s + " z = " + event.z.to_s - else if event isa ASensorGyroscope then - #deal with Gyroscope sensor - #print "ASensorGyroscope : x = " + event.x.to_s + " y = " + event.y.to_s + " z = " + event.z.to_s - else if event isa ASensorLight then - #deal with light sensor - #print "ASensorLight : light = " + event.light.to_s - else if event isa ASensorProximity then - #deal with proximity sensor - #print "ASensorProximity : distance = " + event.distance.to_s - else if event isa MotionEvent then - end - return true - end -end - - -redef class Game - - redef fun input(ie) - do - if ie isa ASensorAccelerometer or ie isa MotionEvent then - ball.intercepts(ie) - return true - end - return false - end -end diff --git a/examples/mnit_ballz/src/ballz_linux.nit b/examples/mnit_ballz/src/ballz_linux.nit deleted file mode 100644 index f3a3db6..0000000 --- a/examples/mnit_ballz/src/ballz_linux.nit +++ /dev/null @@ -1,105 +0,0 @@ -# this file is part of NIT ( http://www.nitlanguage.org ). -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Linux part of mnit_ballz -module ballz_linux - -import mnit::linux -import display - - -redef class App - - private var up_arrow_down = false - private var down_arrow_down = false - private var left_arrow_down = false - private var right_arrow_down = false - private var game: nullable Game is noautoinit - - redef fun run - do - maximum_fps = 50.0 - super - end - - redef fun on_create - do - super - var display = self.display.as(not null) - game = new Game(display.width.to_f, display.height.to_f) - end - - redef fun frame_core(display) - do - if up_arrow_down then input(new SDLKeyEvent("up", true)) - if down_arrow_down then input(new SDLKeyEvent("down", true)) - if left_arrow_down then input(new SDLKeyEvent("left", true)) - if right_arrow_down then input(new SDLKeyEvent("right", true)) - - var game = game - if game != null then - game.do_turn - game.draw(display, assets) - end - end - - redef fun input(ie) - do - if ie isa QuitEvent then - quit = true - return true - end - var game = game - if game != null then - return game.input(ie) - end - return false - end -end - -redef class Ball - - redef fun intercepts(event) - do - var value = 5.0 - if event isa SDLKeyEvent then - if event.is_arrow_left then - acceleration(value, 0.0) - app.left_arrow_down = event.is_down - end - if event.is_arrow_right then - acceleration(-value, 0.0) - app.right_arrow_down = event.is_down - end - if event.is_arrow_up then - acceleration(0.0, -value) - app.up_arrow_down = event.is_down - end - if event.is_arrow_down then - acceleration(0.0, value) - app.down_arrow_down = event.is_down - end - end - return false - end -end - -redef class Game - - redef fun input(ie) - do - ball.intercepts(ie) - return false - end -end diff --git a/examples/mnit_ballz/src/collision.nit b/examples/mnit_ballz/src/collision.nit deleted file mode 100644 index 825cedc..0000000 --- a/examples/mnit_ballz/src/collision.nit +++ /dev/null @@ -1,87 +0,0 @@ -# This file is part of NIT ( http://www.nitlanguage.org ). -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Geometric computations around vectors and points for collision detection -module collision - -import geometry - -# trigonometry - -# Get the distance between `p1` and `p2` -fun distance(p1, p2: Point[Float]): Float -do - var x = p1.x - p2.x - var y = p1.y - p2.y - return ( x * x + y * y ).sqrt -end - -# Get the magnitude (length) of `vector` -fun magnitude(vector: Point[Float]): Float do return ( vector.x * vector.x + vector.y * vector.y ).sqrt - -# Get the unit vector of `vector` -fun unit_vector(vector: Point[Float]): Point[Float] do return new Point[Float](vector.x / magnitude(vector), vector.y / magnitude(vector)) - -# Get the dot product of vectors `v1` and `v2` -fun dot_product(v1, v2: Point[Float]): Float do return v1.x * v2.x + v1.y * v2.y - -# Get the vector between `start_point` and `end_point` -fun vector_between(start_point, end_point: Point[Float]): Point[Float] do return new Point[Float](end_point.x - start_point.x, end_point.y - start_point.y) - -# Returns the point on a line with endpoints `l1` and `l2` closest to `center` -fun point_closest_to_line(center, l1, l2: Point[Float]): Point[Float] -do - var luvector = unit_vector(vector_between(l1, l2)) - var l_to_ball = vector_between(l1, center) - - var projection = dot_product(l_to_ball, luvector) - - if projection <= 0.0 then return l1 - if projection >= distance(l1, l2) then return l2 - return new Point[Float](l1.x + luvector.x * projection, l1.y + luvector.y * projection) -end - -# Is the ball with the `center` and `radius` intersecting the line with the endpoints `l1` and `l2`? -fun is_intersecting(center, l1, l2: Point[Float], radius: Float): Bool -do - var closest = point_closest_to_line(center, l1, l2) - var distance = distance(center, closest) - return distance < radius -end - -# Bouncing function, returns the new point of the center of the ball -fun bounce(center, l1, l2, offset: Point[Float]): Point[Float] -do - var bln = bounce_line_normal(center, l1, l2) - var dot = dot_product(offset, bln) - return new Point[Float](offset.x - (2.0 * dot * bln.x), offset.y - (2.0 * dot * bln.y)) -end - -private fun bounce_line_normal(center, l1, l2: Point[Float]): Point[Float] -do - var p = point_closest_to_line(center, l1, l2) - var v = vector_between(p, center) - return unit_vector(v) -end - -# Rotate `p` around `center` through `angle` -fun rotate_point(p, center: Point[Float], angle: Float): Point[Float] -do - var s = angle.sin - var c = angle.cos - - var nx = c * (p.x - center.x) - s * (p.y - center.y) + center.x - var ny = s * (p.x - center.x) + c * (p.y - center.y) + center.y - return new Point[Float](nx, ny) -end diff --git a/examples/mnit_ballz/src/display.nit b/examples/mnit_ballz/src/display.nit deleted file mode 100644 index 1d63189..0000000 --- a/examples/mnit_ballz/src/display.nit +++ /dev/null @@ -1,47 +0,0 @@ -# this file is part of NIT ( http://www.nitlanguage.org ). -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Handles the drawing of all the game -module display - -import game_logic - -redef class Ball - - # Draw `self` onto `display` with image from `assets` - fun draw(display: Display, assets: Assets) - do - display.blit_centered(assets.ball, center.x, center.y) - end -end - -redef class Wall - - # Draw `self` onto `display` with image from `assets` - fun draw(display: Display, assets: Assets) - do - display.blit_rotated(assets.vertical_wall, center.x, center.y, angle) - end -end - -redef class Game - - # Draw all the entities onto `display` - fun draw(display: Display, assets: Assets) - do - display.clear (0.0, 0.0, 0.0) - ball.draw(display, assets) - for wall in walls do wall.draw(display, assets) - end -end diff --git a/examples/mnit_ballz/src/game_logic.nit b/examples/mnit_ballz/src/game_logic.nit deleted file mode 100644 index 38d7682..0000000 --- a/examples/mnit_ballz/src/game_logic.nit +++ /dev/null @@ -1,183 +0,0 @@ -#this file is part of NIT ( http://www.nitlanguage.org ). -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# All the logic of the game -module game_logic - -import assets -import objects -import geometry::quadtree -import collision - -redef class Ball - - # Scale for drawing the image of `self` - var scale = 1.0 - - # ASensorProximity value for modifying `scale` - # Not used yet - var scale_proximity_modifier = 6.0 - - # Radius of `self` - var radius = 32.0 - - # Movement vector of `self` - var offset = new Point[Float](0.0, 0.0) - - # Calculates the acceleration of `self` - fun acceleration(x,y: Float) - do - var max_offset = 10.0 - var max_value = 9.80 - var offset_x = offset.x - x/max_value - var offset_y = offset.y + y/max_value - if offset_x > max_offset then offset_x = max_offset - if offset_x < -max_offset then offset_x = -max_offset - if offset_y > max_offset then offset_y = max_offset - if offset_y < -max_offset then offset_y = -max_offset - offset = new Point[Float](offset_x, offset_y) - end - - # Do the collision detection, then move `self`consequently - fun do_turn(game: Game) - do - offset = new Point[Float](offset.x * 0.98, offset.y * 0.98) - var np = collision(game.quadtree) - if np != null then - offset = np - center = new Point[Float](center.x + offset.x, center.y + offset.y) - else - center = new Point[Float](center.x + offset.x, center.y + offset.y) - end - end - - # Collision detection - fun collision(quadtree: SQuadTree[OrientedLine]): nullable Point[Float] - do - - var nx = self.center.x + offset.x - var ny = self.center.y + offset.y - var new_center = new Point[Float](nx, ny) - var effective_radius = radius*scale - # Lines intersecting with the ball - var intersecting_lines = new Array[OrientedLine] - - # Line intersecting closest to the ball - var intersecting_line: nullable OrientedLine = null - - # closest point of the intersecting line - var closest_point: nullable Point[Float] = null - - # get the intersecting lines with help of the quadtree - var lines = quadtree.items_overlapping(new_center.padded(effective_radius)) - for l in lines do - if is_intersecting(new_center, l.point_left, l.point_right, effective_radius) then - intersecting_lines.add(l) - end - end - - # get the line closest to the ball from the intersecting lines, setting the closest point - var min_dist = 100.0 - if intersecting_lines.length >= 2 then - for l in intersecting_lines do - var closest = point_closest_to_line(new_center, l.point_left, l.point_right) - var distance = distance(closest, new_center) - if distance < min_dist then - min_dist = distance - intersecting_line = l - closest_point = closest - end - end - else if intersecting_lines.length == 1 then - intersecting_line = intersecting_lines[0] - closest_point = point_closest_to_line(new_center, intersecting_line.point_left, intersecting_line.point_right) - end - - if intersecting_line != null and closest_point != null then - return bounce(center, intersecting_line.point_left, intersecting_line.point_right, offset) - end - return null - end - - # Event interception - fun intercepts(event: InputEvent): Bool is abstract -end - -# The core of the game -class Game - - # The Ball! - var ball: Ball is noinit - - # List of walls in the level - var walls: Array[Wall] is noinit - - # Width of the display - var width: Float - - # Heightof the display - var height: Float - - # Quadtree used for collision detection - var quadtree: SQuadTree[OrientedLine] is noinit - - init - do - ball = new Ball(new Point[Float](width/2.0, height/2.0)) - # Walls initialisation - var walla = new Wall(new Point[Float](width/4.0, height/4.0), pi/3.0, 1.0) - var wallb = new Wall(new Point[Float](width*0.75, height/4.0), 0.0, 1.0) - var wallc = new Wall(new Point[Float](width/4.0, height*0.75), 0.0, 1.0) - var walld = new Wall(new Point[Float](width*0.75, height*0.75), pi/3.0, 1.0) - walls = new Array[Wall].with_items(walla, wallb, wallc, walld) - - # adding screen bordures - var i = new Point[Float](0.0,0.0) - var a = new Point[Float](0.0, height/2.0) - var b = new Point[Float](width/2.0, 0.0) - var c = new Point[Float](width, height/2.0) - var d = new Point[Float](width/2.0, height) - - var l1 = new OrientedLine(i, i, pi/2.0, height, a) - var l2 = new OrientedLine(i, i, 0.0, width, b) - var l3 = new OrientedLine(i, i, pi/2.0, height, c) - var l4 = new OrientedLine(i, i, 0.0, width, d) - - quadtree = new SQuadTree[OrientedLine](5, width, height) - for w in walls do for l in w.lines do - quadtree.add(l) - end - quadtree.add(l1) - quadtree.add(l2) - quadtree.add(l3) - quadtree.add(l4) - end - - # Only calls `do_turn` of the ball for the moment - fun do_turn do ball.do_turn(self) - - # Input gestion - fun input(ie: InputEvent): Bool do return false -end - -redef class App - - # Assets used in all the app - var assets = new Assets - - redef fun on_create do - super - assets.load - end -end diff --git a/examples/mnit_ballz/src/objects.nit b/examples/mnit_ballz/src/objects.nit deleted file mode 100644 index d8e1686..0000000 --- a/examples/mnit_ballz/src/objects.nit +++ /dev/null @@ -1,100 +0,0 @@ -# This file is part of NIT ( http://www.nitlanguage.org ). -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Module containing all objects of the game -module objects - -import geometry -import geometry::polygon -import geometry::boxes -import collision - -# The ball is the main character of the game! -class Ball - # Center of the ball - var center: Point[Float] is writable -end - -# Walls make the ball bounce on them -class Wall - # Coordinates of the center of the wall - var center: Point[Float] - - # Angle in radian - var angle: Float - - # Scale for drawing `self` - var scale: Float - - # Width of `self` - var width: Float is noautoinit - - # Height of `self` - var height: Float is noautoinit - - # Lines composing `self` - var lines: Array[OrientedLine] is noautoinit - - # Initialize `self` with all its lines from `center` and `angle` - init do - self.height = 128.0 - self.width = 32.0 - var i = new Point[Float](0.0, 0.0) - var j = new Point[Float](0.0, 0.0) - - var a = new Point[Float]((center.x - width/2.0), center.y) - var b = new Point[Float]((center.x), (center.y - height/2.0)) - var c = new Point[Float]((center.x + width/2.0), center.y) - var d = new Point[Float]((center.x), (center.y + height/2.0)) - - var l1 = new OrientedLine(i, j, angle - pi/2.0, height * scale.to_f, rotate_point(a, center, angle)) - var l2 = new OrientedLine(i, j, angle, width * scale.to_f, rotate_point(b, center, angle)) - var l3 = new OrientedLine(i, j, angle - pi/2.0, height * scale.to_f, rotate_point(c, center, angle)) - var l4 = new OrientedLine(i, j, angle, width * scale.to_f, rotate_point(d, center, angle)) - lines = new Array[OrientedLine] - lines.add_all([l1, l2, l3, l4]) - end -end - -# A line represented with a center and an angle -class OrientedLine - super Line[Float] - redef type P: Point[Float] - - # Angle in radian - var angle: Float is writable - - # Length - var length: Float - - # Center - var center: Point[Float] - - redef fun point_left - do - var luv = unit_vector(new Point[Float](angle.cos, angle.sin)) - var offset_from_center = new Point[Float](luv.x * (length / 2.0), luv.y * (length / 2.0)) - return new Point[Float](center.x + offset_from_center.x, center.y + offset_from_center.y) - end - - redef fun point_right - do - var luv = unit_vector(new Point[Float](angle.cos, angle.sin)) - var offset_from_center = new Point[Float](luv.x * length / 2.0, luv.y * length / 2.0) - return new Point[Float](center.x - offset_from_center.x, center.y - offset_from_center.y) - end - - redef fun left do return point_left.x.min(point_right.x) - redef fun right do return point_left.x.max(point_right.x) -end