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.
sides { _v.count } // returns the number of sides of the curent instance
static new(vertices) { new(vertices, "") }
vertices { _v.toList } // returns a shallow copy of the current instance's vertices

static quick(vertices) { quick(vertices, "") }

static regular(n, cx, cy, r, sa) { regular(n, cx, cy, r, sa, "") }

// Properties
sides { _v.count } // returns the number of sides of the curent instance
vertices { _v.toList } // returns a shallow copy of the current instance's vertices
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("All arguments must be numbers.")
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 Rectangle object with center (cx, cy) and side s.
// 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.