chore: translated Rectangle

This commit is contained in:
cha0s 2019-03-19 13:49:21 -05:00
parent 97ad01b426
commit daf6eeddc7
3 changed files with 210 additions and 168 deletions

View File

@ -1,4 +1,7 @@
// export * as Matrix from './matrix';
// export * as Rectangle from './rectangle';
import * as Rectangle from './rectangle';
export {Rectangle};
import * as Vector from './vector';
export {Vector};

View File

@ -1,167 +0,0 @@
# Rectangle operations.
# **Rectangle** is a utility class to help with rectangle operations. A
# rectangle is implemented as a 4-element array. Element 0 is *x*, element
# 1 is *y*, element 2 is *width* and element 3 is *height*.
import * as Vector from '../vector'
# Check if a rectangle intersects with another rectangle.
#
# avocado> Rectangle.intersects [0, 0, 16, 16], [8, 8, 24, 24]
# true
#
# avocado> Rectangle.intersects [0, 0, 16, 16], [16, 16, 32, 32]
# false
export intersects = (l, r) ->
return false if l[0] >= r[0] + r[2]
return false if r[0] >= l[0] + l[2]
return false if l[1] >= r[1] + r[3]
return false if r[1] >= l[1] + l[3]
return true
# Check if a rectangle is touching a vector.
#
# avocado> Rectangle.isTouching [0, 0, 16, 16], [0, 0]
# true
#
# avocado> Rectangle.intersects [0, 0, 16, 16], [16, 16]
# false
export isTouching = (r, v) ->
return false if v[0] < r[0]
return false if v[1] < r[1]
return false if v[0] >= r[0] + r[2]
return false if v[1] >= r[1] + r[3]
return true
# Compose a rectangle from a position vector and a size vector.
#
# avocado> Rectangle.compose [0, 0], [16, 16]
# [0, 0, 16, 16]
export compose = (l, r) -> [l[0], l[1], r[0], r[1]]
# Make a deep copy of the rectangle.
#
# avocado> rectangle = [0, 0, 16, 16]
# avocado> rectangle is Rectangle.copy rectangle
# false
export copy = (r) -> [r[0], r[1], r[2], r[3]]
# Convert a rectangle to an object. If you *useShortKeys*, The width and
# height keys will be named w and h, respectively.
#
# avocado> Rectangle.toObject [3, 4, 5, 6]
# {x: 3, y: 4, width: 5, height: 6}
#
# avocado> Rectangle.toObject [3, 4, 5, 6], true
# {x: 3, y: 4, w: 5, h: 6}
export toObject = (r, useShortKeys = false) ->
whKeys = if useShortKeys then ['w', 'h'] else ['width', 'height']
O = x: r[0], y: r[1]
O[whKeys[0]] = r[2]
O[whKeys[1]] = r[3]
return O
export fromObject = (O) -> [O.x, O.y, O.width, O.height]
# Returns the position of a rectangle.
#
# avocado> Rectangle.position [8, 8, 16, 16]
# [8, 8]
export position = (r) -> [r[0], r[1]]
# Returns the size of a rectangle.
#
# avocado> Rectangle.size [8, 8, 16, 16]
# [16, 16]
export size = (r) -> [r[2], r[3]]
# Compute the intersection rectangle of two rectangles.
#
# avocado> Rectangle.intersection [0, 0, 16, 16], [8, 8, 24, 24]
# [8, 8, 8, 8]
export intersection = (l, r) ->
return [0, 0, 0, 0] unless intersects l, r
x = Math.max l[0], r[0]
y = Math.max l[1], r[1]
lx2 = l[0] + l[2]
rx2 = r[0] + r[2]
ly2 = l[1] + l[3]
ry2 = r[1] + r[3]
w = (if lx2 <= rx2 then lx2 else rx2) - x
h = (if ly2 <= ry2 then ly2 else ry2) - y
return [x, y, w, h]
# Returns a rectangle translated along the [*x*, *y*] axis of a vector.
#
# avocado> Rectangle.translated [0, 0, 16, 16], [8, 8]
# [8, 8, 16, 16]
export translated = (r, v) -> compose(
Vector.add v, position r
size r
)
# Checks if a rectangle is null. A null rectangle is defined by having any
# 0-length axis.
#
# avocado> Rectangle.isNull [0, 0, 1, 1]
# false
#
# avocado> Rectangle.isNull [0, 0, 1, 0]
# true
export isNull = (r) ->
return true unless r?
return true unless r.length is 4
return Vector.isNull size r
# Check whether a rectangle equals another rectangle.
#
# avocado> Rectangle.equals [0, 0, 0, 0], [0, 0, 0, 1]
# false
#
# avocado> Rectangle.equals [0, 0, 0, 0], [0, 0, 0, 0]
# true
export equals = (l, r) ->
return l[0] is r[0] and l[1] is r[1] and l[2] is r[2] and l[3] is r[3]
# Returns a rectangle that is the united area of two rectangles.
#
# avocado> Rectangle.united [0, 0, 4, 4], [4, 4, 8, 8]
# [0, 0, 12, 12]
export united = (l, r) ->
return r if isNull l
return l if isNull r
x = Math.min l[0], r[0]
y = Math.min l[1], r[1]
x2 = Math.max l[0] + l[2], r[0] + r[2]
y2 = Math.max l[1] + l[3], r[1] + r[3]
return [x, y, x2 - x, y2 - y]
# Round the position and size of a rectangle.
#
# avocado> Rectangle.round [3.14, 4.70, 5.32, 1.8]
# [3, 5, 5, 2]
export round = (r) -> r.map Math.round
# Floor the position and size of a rectangle.
#
# avocado> Rectangle.floor [3.14, 4.70, 5.32, 1.8]
# [3, 4, 5, 1]
export floor = (r) -> r.map Math.floor

View File

@ -0,0 +1,206 @@
// Rectangle operations.
// **Rectangle** is a utility class to help with rectangle operations. A
// rectangle is implemented as a 4-element array. Element 0 is *x*, element
// 1 is *y*, element 2 is *width* and element 3 is *height*.
import * as Vector from '../vector';
// Check if a rectangle intersects with another rectangle.
//
// avocado> Rectangle.intersects [0, 0, 16, 16], [8, 8, 24, 24]
// true
//
// avocado> Rectangle.intersects [0, 0, 16, 16], [16, 16, 32, 32]
// false
export function intersects (l, r) {
if (l[0] >= r[0] + r[2]) {
return false;
}
if (r[0] >= l[0] + l[2]) {
return false;
}
if (l[1] >= r[1] + r[3]) {
return false;
}
if (r[1] >= l[1] + l[3]) {
return false;
}
return true;
}
// Check if a rectangle is touching a vector.
//
// avocado> Rectangle.isTouching [0, 0, 16, 16], [0, 0]
// true
//
// avocado> Rectangle.intersects [0, 0, 16, 16], [16, 16]
// false
export function isTouching (r, v) {
if (v[0] < r[0]) {
return false;
}
if (v[1] < r[1]) {
return false;
}
if (v[0] >= r[0] + r[2]) {
return false;
}
if (v[1] >= r[1] + r[3]) {
return false;
}
return true
}
// Compose a rectangle from a position vector and a size vector.
//
// avocado> Rectangle.compose [0, 0], [16, 16]
// [0, 0, 16, 16]
export function compose (l, r) {
return [l[0], l[1], r[0], r[1]];
}
// Make a deep copy of the rectangle.
//
// avocado> rectangle = [0, 0, 16, 16]
// avocado> rectangle is Rectangle.copy rectangle
// false
export function copy (r) {
return [r[0], r[1], r[2], r[3]];
}
// Convert a rectangle to an object. If you *useShortKeys*, The width and
// height keys will be named w and h, respectively.
//
// avocado> Rectangle.toObject [3, 4, 5, 6]
// {x: 3, y: 4, width: 5, height: 6}
//
// avocado> Rectangle.toObject [3, 4, 5, 6], true
// {x: 3, y: 4, w: 5, h: 6}
export function toObject (r, useShortKeys = false) {
const whKeys = useShortKeys ? ['w', 'h'] : ['width', 'height'];
const O = {x: r[0], y: r[1]};
O[whKeys[0]] = r[2];
O[whKeys[1]] = r[3];
return O;
}
export function fromObject(O) {
return [O.x, O.y, O.width, O.height];
}
// Returns the position of a rectangle.
//
// avocado> Rectangle.position [8, 8, 16, 16]
// [8, 8]
export function position(r) {
return [r[0], r[1]];
}
// Returns the size of a rectangle.
//
// avocado> Rectangle.size [8, 8, 16, 16]
// [16, 16]
export function size(r) {
return [r[2], r[3]];
}
// Compute the intersection rectangle of two rectangles.
//
// avocado> Rectangle.intersection [0, 0, 16, 16], [8, 8, 24, 24]
// [8, 8, 8, 8]
export function intersection(l, r) {
if (!intersects(l, r)) {
return [0, 0, 0, 0];
}
const x = Math.max(l[0], r[0]);
const y = Math.max(l[1], r[1]);
const lx2 = l[0] + l[2];
const rx2 = r[0] + r[2];
const ly2 = l[1] + l[3];
const ry2 = r[1] + r[3];
const w = (lx2 <= rx2 ? lx2 : rx2) - x;
const h = (ly2 <= ry2 ? ly2 : ry2) - y;
return [x, y, w, h];
}
// Returns a rectangle translated along the [*x*, *y*] axis of a vector.
//
// avocado> Rectangle.translated [0, 0, 16, 16], [8, 8]
// [8, 8, 16, 16]
export function translated(r, v) {
return compose(Vector.add(v, position(r)), size(r));
}
// Checks if a rectangle is null. A null rectangle is defined by having any
// 0-length axis.
//
// avocado> Rectangle.isNull [0, 0, 1, 1]
// false
//
// avocado> Rectangle.isNull [0, 0, 1, 0]
// true
export function isNull(r) {
if (!r) {
return true;
}
if (4 !== r.length) {
return true;
}
return Vector.isNull(size(r));
}
// Check whether a rectangle equals another rectangle.
//
// avocado> Rectangle.equals [0, 0, 0, 0], [0, 0, 0, 1]
// false
//
// avocado> Rectangle.equals [0, 0, 0, 0], [0, 0, 0, 0]
// true
export function equals(l, r) {
return l[0] === r[0] && l[1] === r[1] && l[2] === r[2] && l[3] === r[3];
}
// Returns a rectangle that is the united area of two rectangles.
//
// avocado> Rectangle.united [0, 0, 4, 4], [4, 4, 8, 8]
// [0, 0, 12, 12]
export function united(l, r) {
if (isNull(l)) {
return r;
}
if (isNull(r)) {
return l;
}
const x = Math.min(l[0], r[0]);
const y = Math.min(l[1], r[1]);
const x2 = Math.max(l[0] + l[2], r[0] + r[2]);
const y2 = Math.max(l[1] + l[3], r[1] + r[3]);
return [x, y, x2 - x, y2 - y];
}
// Round the position and size of a rectangle.
//
// avocado> Rectangle.round [3.14, 4.70, 5.32, 1.8]
// [3, 5, 5, 2]
export function round(r) {
return [
Math.round(r[0]),
Math.round(r[1]),
Math.round(r[2]),
Math.round(r[3]),
];
}
// Floor the position and size of a rectangle.
//
// avocado> Rectangle.floor [3.14, 4.70, 5.32, 1.8]
// [3, 4, 5, 1]
export function floor(r) {
return [
Math.floor(r[0]),
Math.floor(r[1]),
Math.floor(r[2]),
Math.floor(r[3]),
];
}