Category talk:Wren-polygon: Difference between revisions
Content added Content deleted
(→Source code: Added convenience classes: Rectangle and Square.) |
m (→Source code: Infrastructure changes to enable all polygons to be treated as buttons and to make it easier to track button clicks.) |
||
Line 5: | Line 5: | ||
import "graphics" for Canvas, Color |
import "graphics" for Canvas, Color |
||
import "math" for Point |
import "math" for Point |
||
/* Selectable is an abstract class representing the interface needed for an identifiable |
|||
object to be selectable by mouse click or otherwise */ |
|||
class Selectable { |
|||
tag { "" } |
|||
tag=(t) {} |
|||
selected { false } |
|||
selected=(s) {} |
|||
contains(x, y) { false } |
|||
} |
|||
/* Polygon represents a polygon in 2 dimensional space. */ |
/* Polygon represents a polygon in 2 dimensional space. */ |
||
class Polygon { |
class Polygon is Selectable { |
||
// Constructs a new Polygon object from its vertices. |
// Constructs a new Polygon object from its vertices and tag. |
||
construct new(vertices) { |
construct new(vertices, tag) { |
||
if (vertices.count < 3) Fiber.abort("Number of vertices cannot be less than 3.") |
if (vertices.count < 3) Fiber.abort("Number of vertices cannot be less than 3.") |
||
if (vertices[0].type != List || vertices[0].count != 2 || vertices[0][0].type != Num) { |
if (vertices[0].type != List || vertices[0].count != 2 || vertices[0][0].type != Num) { |
||
Line 15: | Line 27: | ||
} |
} |
||
_v = vertices.toList |
_v = vertices.toList |
||
_tag = tag |
|||
_selected = false |
|||
} |
} |
||
// Constructs a new Polygon object from its vertices without checking or copying them. |
// Constructs a new Polygon object from its vertices and tag without checking or copying them. |
||
construct quick(vertices) { |
construct quick(vertices, tag) { |
||
_v = vertices |
_v = vertices |
||
_tag = tag |
|||
_selected = false |
|||
} |
} |
||
Line 25: | Line 41: | ||
// center to each vertex and start angle sa in degrees measured clockwise from the horizonal line |
// center to each vertex and start angle sa in degrees measured clockwise from the horizonal line |
||
// drawn to the polygon's rightmost point. |
// drawn to the polygon's rightmost point. |
||
static regular(n, cx, cy, r, sa) { |
static regular(n, cx, cy, r, sa, tag) { |
||
var vertices = List.filled(n, null) |
var vertices = List.filled(n, null) |
||
var inc = 360 / n |
var inc = 360 / n |
||
Line 36: | Line 52: | ||
angle = angle + inc |
angle = angle + inc |
||
} |
} |
||
return Polygon.new(vertices) |
return Polygon.new(vertices, tag) |
||
} |
} |
||
// Convenience versions of the above constructors for objects with an empty tag. |
|||
⚫ | |||
static new(vertices) { new(vertices, "") } |
|||
⚫ | |||
static quick(vertices) { quick(vertices, "") } |
|||
static regular(n, cx, cy, r, sa) { regular(n, cx, cy, r, sa, "") } |
|||
// Properties |
|||
⚫ | |||
⚫ | |||
tag { _tag } // gets the tag of the current instance |
|||
tag=(t) { _tag = t } // sets the tag of the current instance |
|||
selected { _selected } // gets whether the current instance is selected or not. |
|||
selected=(s) { _selected = s } // sets whether the current instance is selected or not. |
|||
// Returns what kind of polygon this instance is. |
// Returns what kind of polygon this instance is. |
||
Line 160: | Line 188: | ||
class Rectangle is Polygon { |
class Rectangle is Polygon { |
||
// Constructs a new Rectangle object with top left corner (x, y), width w and height h. |
// Constructs a new Rectangle object with top left corner (x, y), width w and height h. |
||
construct new (x, y, w, h) { |
construct new (x, y, w, h, tag) { |
||
if (!((x is Num) && (y is Num) && (w is Num) && (h is Num))) { |
if (!((x is Num) && (y is Num) && (w is Num) && (h is Num))) { |
||
Fiber.abort(" |
Fiber.abort("First four arguments must be numbers.") |
||
} |
} |
||
super([[x, y], [x + w, y], [x + w, y + h] , [x, y + h]]) |
super([[x, y], [x + w, y], [x + w, y + h] , [x, y + h]], tag) |
||
_x = x |
_x = x |
||
_y = y |
_y = y |
||
Line 172: | Line 200: | ||
// Constructs a new Rectangle object with center (cx, cy), width w and height h. |
// Constructs a new Rectangle object with center (cx, cy), width w and height h. |
||
static fromCenter(cx, cy, w, h) { new(cx - w/2, cy - h/2, w, h) } |
static fromCenter(cx, cy, w, h, tag) { new(cx - w/2, cy - h/2, w, h, tag) } |
||
// Convenience versions of the above constructors for objects with an empty tag. |
|||
static new(x, y, w, h) { new(x, y, w, h, "") } |
|||
static fromCenter(cx, cy, w, h) { fromCenter(cx, cy, w, h, "") } |
|||
// Properties |
// Properties |
||
x { _x } |
x { _x } |
||
Line 191: | Line 224: | ||
class Square is Rectangle { |
class Square is Rectangle { |
||
// Constructs a new Square object with top left corner (x, y) and side s. |
// Constructs a new Square object with top left corner (x, y) and side s. |
||
construct new (x, y, s) { |
construct new (x, y, s, tag) { |
||
super(x, y, s, s) |
super(x, y, s, s, tag) |
||
_s = s |
_s = s |
||
} |
} |
||
// Constructs a new |
// Constructs a new Square object with center (cx, cy) and side s. |
||
static fromCenter(cx, cy, s) { new(cx - s/2, cy - s/2, s) } |
static fromCenter(cx, cy, s, tag) { new(cx - s/2, cy - s/2, s, tag) } |
||
// Convenience versions of the above constructors for objects with an empty tag. |
|||
static new(x, y, s) { new(x, y, s, "") } |
|||
static fromCenter(cx, cy, s) { fromCenter(cx, cy, s, "") } |
|||
// Properties. |
// Properties. |