summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJules Laplace <jules@okfoc.us>2014-11-03 12:45:43 -0500
committerJules Laplace <jules@okfoc.us>2014-11-03 12:45:43 -0500
commitb520c42277cfa0638963142bf7bc087f8ab24b8c (patch)
treeb6eb0d0b26826dca28bfdd32b66de62ab99dcbc1
parent22bf04c9b56fafadc3c3be54dceb6665243331cd (diff)
parent18f1bc14f610cdb0dddd273e8c55ea5c2e547a94 (diff)
merge
-rw-r--r--public/assets/javascripts/rectangles/engine/rooms/mover.js283
-rw-r--r--public/assets/javascripts/rectangles/models/wall.js28
-rwxr-xr-xpublic/assets/stylesheets/app.css55
-rw-r--r--public/assets/test/intersect3.html164
4 files changed, 365 insertions, 165 deletions
diff --git a/public/assets/javascripts/rectangles/engine/rooms/mover.js b/public/assets/javascripts/rectangles/engine/rooms/mover.js
index 8ce00fe..5682be8 100644
--- a/public/assets/javascripts/rectangles/engine/rooms/mover.js
+++ b/public/assets/javascripts/rectangles/engine/rooms/mover.js
@@ -4,6 +4,15 @@ Rooms.mover = new function(){
base.room = null
base.noclip = false
+ var cursor = base.cursor = new Rect (0,0,0,0)
+ var cursor_copy = new Rect (0,0,0,0)
+ var wall_vec = new Rect (0,0,0,0)
+ var intersect = new vec2(0,0)
+
+ var origins = new Rect()
+ origins.x = cursor.x
+ origins.y = wall_vec.x
+
base.init = function(){
base.bind()
base.update(scene.camera)
@@ -20,6 +29,7 @@ Rooms.mover = new function(){
}
base.update = function(pos){
+ var intersect, collision, distance
var radius = scene.camera.radius
cam.y = pos.y
@@ -33,14 +43,37 @@ Rooms.mover = new function(){
return
}
- // check if we've breached one of the walls.. clamp position if so
- var collision = base.room.collidesDisc(cam, pos, radius)
-
- if (collision && ! base.noclip) {
- cam.x = (collision & LEFT_RIGHT) ? base.room.rect.x.clampDisc(pos.x, radius) : pos.x
- cam.z = (collision & FRONT_BACK) ? base.room.rect.y.clampDisc(pos.z, radius) : pos.z
- return
+ distance = sqrt(pow(cam.x-pos.x, 2), pow(cam.z-pos.z, 2))
+
+ // check if we've breached one of the walls.. clamp position if so.
+ // there are two algorithms for this now, ridiculously..
+ // - the first one is smoother, best for keyboard use
+ // but if the distance travelled is greater than the min. distance from the wall,
+ // then there is a possibility of ejection from the room. so is bad for phone/mousewheel.
+
+ // - the second one determines fortuitously if we have breached any of the walls
+ // however it can get jumpy if you run into a wall.. thus it is best for devices like phone or mousewheel
+ // the benefit is you will never leave the room.
+ if (base.noclip) {
+ // in no-clip mode we walk through walls.
}
+ else if (distance < radius) {
+ collision = base.room.collidesDisc(cam, pos, radius)
+
+ if (collision) {
+ cam.x = (collision & LEFT_RIGHT) ? base.room.rect.x.clampDisc(pos.x, radius) : pos.x
+ cam.z = (collision & FRONT_BACK) ? base.room.rect.y.clampDisc(pos.z, radius) : pos.z
+ return
+ }
+ }
+ else {
+ intersect = base.intersect(pos)
+ if (intersect) {
+ cam.x = intersect.a
+ cam.z = intersect.b
+ return
+ }
+ }
// in this case, we appear to have left the room..
// $(".face.active").removeClass("active")
@@ -48,89 +81,6 @@ Rooms.mover = new function(){
base.room = null
}
-/*
- var dz = new vec2( cam.z, pos.z )
- dz.normalize()
-
- var dx = new vec2( cam.x, pos.x )
- dx.normalize()
-
- // first check if the cam-pos movement intersects the wall.
- // next check if it intersects any of the surface frames
- // if we can pass through the wall at this point, we do not need to clamp.
- // otherwise, get the distance along the cam-pos vector where we would hit the wall and clamp to it.
- Walls.list.forEach(function(wall){
- var t = -1
- switch (wall.side) {
- case FRONT:
- if (cam.z >= wall.edge + radius && wall.edge + radius >= pos.z && wall.vec.intersects(dx) ) {
- t = check_intersection( front_back_intersection, cam, pos, dx, wall, radius )
- }
- break
- case BACK:
- // console.log(cam.z|0, wall.edge-radius, pos.z|0, wall.vec.intersects(dx))
- if (cam.z <= wall.edge - radius && wall.edge - radius <= pos.z && wall.vec.intersects(dx) ) {
- t = check_intersection( front_back_intersection, cam, pos, dx, wall, -radius )
- console.log(t)
- }
- break
- case LEFT:
- if (cam.x >= wall.edge + radius && wall.edge + radius >= pos.x && wall.vec.intersects(dz) ) {
- t = check_intersection( left_right_intersection, cam, pos, dz, wall, radius )
- }
- break
- case RIGHT:
- if (cam.x <= wall.edge - radius && wall.edge - radius <= pos.x && wall.vec.intersects(dz) ) {
- t = check_intersection( left_right_intersection, cam, pos, dz, wall, -radius )
- }
- break
- }
- if (0 <= t && t <= 1) {
- pos.x = cam.x + (pos.x - cam.x) * t
- pos.z = cam.z + (pos.z - cam.z) * t
-
- dz = new vec2( cam.z, pos.z )
- dz.normalize()
-
- dx = new vec2( cam.x, pos.x )
- dx.normalize()
- }
- })
-
- function check_intersection(intersection_function, cam, pos, cam_pos_vector, wall, radius) {
- var t = -1
- wall.surface.faces.some(function(face, i){
- if (face.y.a == 0 && face.x.intersects(cam_pos_vector)) {
- t = intersection_function( cam, pos, wall, face, radius )
- console.log(">>", t)
- if (0 <= t && t <= 1) {
- return true
- }
- else {
- t = -1
- }
- }
- return false
- })
- return t
- }
- function left_right_intersection (cam, pos, wall, face, radius) {
- var perp_n = (face.x.a - face.x.b) * (wall.edge - cam.z + radius)
- var perp_d = (face.x.a - face.x.b) * (pos.z - cam.z)
- if (perp_d == 0) return Infinity
- return perp_n / perp_d
- }
- function front_back_intersection (cam, pos, wall, face, radius) {
- // va.vx*vb.vy - va.vy*vb.vx
- var perp_n = (face.x.b - face.x.a) * (wall.edge - cam.x + radius)
- var perp_d = (face.x.b - face.x.a) * (pos.x - cam.x)
-
- console.log((pos.x - cam.x), wall.edge - cam.x, radius)
-
- if (perp_d == 0) return Infinity
- return perp_n / perp_d
- }
-*/
// collision test failed, so update position
cam.x = pos.x
cam.z = pos.z
@@ -148,7 +98,158 @@ Rooms.mover = new function(){
}
app.tube("change-room", { room: base.room })
}
-
}
+ base.intersect = function(pos){
+ var closest_intersect, closest_wall, new_t, wall_t, t, min_t = 1
+
+ cursor_copy.x.a = cursor.x.a = cam.x
+ cursor_copy.x.b = cursor.x.b = cam.z
+ cursor_copy.y.a = cursor.y.a = pos.x
+ cursor_copy.y.b = cursor.y.b = pos.z
+
+ cursor_copy.extend_ends(scene.camera.radius)
+
+ origins.x = cursor_copy.x
+ origins.y = wall_vec.x
+
+ Walls.list.forEach(function(wall, i){
+ var actually_intersects = false, intersecting_face
+
+ wall.get_points(wall_vec)
+
+
+ t = perp(origins, wall_vec) / ( perp(cursor_copy, wall_vec) || 0.0000001 )
+
+ if ( min_t < t || t < 0 || 1 < t ) return
+
+ intersect.a = cursor_copy.x.a + ( cursor_copy.y.a - cursor_copy.x.a ) * t
+ intersect.b = cursor_copy.x.b + ( cursor_copy.y.b - cursor_copy.x.b ) * t
+ if ( ! is_collinear( intersect, wall_vec ) ) return
+
+ if (wall.side & LEFT_RIGHT) {
+ intersecting_face = wall.surface.face_for_x(intersect.b)
+ }
+ else {
+ intersecting_face = wall.surface.face_for_x(intersect.a)
+ }
+
+ actually_intersects = !! (intersecting_face && intersecting_face.y.a == 0)
+ if (actually_intersects) {
+ closest_intersect = intersect.clone()
+ closest_wall = wall_vec.clone()
+ min_t = t
+ }
+ })
+
+ if (closest_intersect) {
+
+ var aw, len, dd
+ aw = angle(closest_wall)
+ wall_vec.assign(closest_wall)
+ wall_vec.x.a -= scene.camera.radius * sin(aw)
+ wall_vec.x.b += scene.camera.radius * cos(aw)
+ wall_vec.y.a -= scene.camera.radius * sin(aw)
+ wall_vec.y.b += scene.camera.radius * cos(aw)
+
+ origins.x = cursor.x
+ origins.y = wall_vec.x
+
+ new_t = perp(origins, wall_vec) / ( perp(cursor, wall_vec) || 0.0000001 )
+ wall_t = perp(origins, cursor) / ( perp(wall_vec, cursor) || 0.0000001 )
+
+ intersect.a = cursor.x.a + ( cursor.y.a - cursor.x.a ) * new_t
+ intersect.b = cursor.x.b + ( cursor.y.b - cursor.x.b ) * new_t
+
+ // here compare len to the length of the wall in the direction we are travelling
+ dd = dot2(diff(closest_wall), diff(cursor))
+ len = sqrt(dot(wall_vec, wall_vec))
+
+ if (dd > 0) {
+ len *= 1-abs(wall_t)
+ }
+ else {
+ len *= abs(wall_t)
+ aw += PI
+ }
+
+ len = clamp(len, 0, (1-min_t) * sqrt(dot(cursor, cursor)))
+
+ intersect.a += len * cos(aw)
+ intersect.b += len * sin(aw)
+
+ wall_vec.normalize()
+ intersect.a = clamp(intersect.a, wall_vec.x.a, wall_vec.y.a)
+ intersect.b = clamp(intersect.b, wall_vec.x.b, wall_vec.y.b)
+
+ return intersect
+ }
+ else {
+ return cursor.y
+ }
+ }
+ function diff (v) {
+ return new vec2(v.y.a - v.x.a, v.y.b - v.x.b)
+ }
+ function angle (va) {
+ return atan2(va.y.b - va.x.b, va.y.a - va.x.a)
+ }
+ function angle2 (pa, pb) {
+ return atan2(pb.b - pa.b, pb.a - pa.a)
+ }
+ function normal (va) {
+ return atan2(va.x.a - va.y.a, va.y.b - va.x.b)
+ }
+ function dot (va, vb) {
+ return (va.y.a - va.x.a) * (vb.y.a - vb.x.a) + (va.y.b - va.x.b) * (vb.y.b - vb.x.b)
+ }
+ function dot2 (pa, pb) {
+ return pa.a * pb.a + pa.b * pb.b
+ }
+ function perp (va, vb) {
+ return (va.y.a - va.x.a) * (vb.y.b - vb.x.b) - (va.y.b - va.x.b) * (vb.y.a - vb.x.a)
+ }
+ function is_collinear (p, vec) {
+ var on_x, on_y
+ var pa = round(p.a), pb = round(p.b)
+
+ if (vec.x.a < vec.y.a) {
+ on_x = vec.x.a <= pa && pa <= vec.y.a
+ }
+ else {
+ on_x = vec.x.a >= pa && pa >= vec.y.a
+ }
+
+ if (vec.x.b < vec.y.b) {
+ on_y = vec.x.b <= pb && pb <= vec.y.b
+ }
+ else {
+ on_y = vec.x.b >= pb && pb >= vec.y.b
+ }
+
+ return !! (on_x && on_y)
+ }
+ cursor_copy.extend_ends = function(n){
+ var a = angle(this)
+ this.x.a -= n*cos(a)
+ this.x.b -= n*sin(a)
+ this.y.a += n*cos(a)
+ this.y.b += n*sin(a)
+ return this
+ }
+ wall_vec.normalize = function(){
+ var carry
+ if (this.x.a > this.y.a) {
+ console.log("SWAP X")
+ carry = this.x.a
+ this.x.a = this.y.a
+ this.y.a = carry
+ }
+ if (this.x.b > this.y.b) {
+ console.log("SWAP Y")
+ carry = this.x.b
+ this.x.b = this.y.b
+ this.y.b = carry
+ }
+ }
}
diff --git a/public/assets/javascripts/rectangles/models/wall.js b/public/assets/javascripts/rectangles/models/wall.js
index 8590de7..a026c3c 100644
--- a/public/assets/javascripts/rectangles/models/wall.js
+++ b/public/assets/javascripts/rectangles/models/wall.js
@@ -25,6 +25,34 @@
Wall.prototype.toString = function(){
return this.vec.toString()
}
+ Wall.prototype.get_points = function(wall_vec){
+ wall_vec = wall_vec || new Rect ()
+ if (this.side & LEFT) {
+ wall_vec.x.a = this.edge
+ wall_vec.x.b = this.vec.b
+ wall_vec.y.a = this.edge
+ wall_vec.y.b = this.vec.a
+ }
+ else if (this.side & RIGHT) {
+ wall_vec.x.a = this.edge
+ wall_vec.x.b = this.vec.a
+ wall_vec.y.a = this.edge
+ wall_vec.y.b = this.vec.b
+ }
+ else if (this.side & FRONT) {
+ wall_vec.x.a = this.vec.a
+ wall_vec.x.b = this.edge
+ wall_vec.y.a = this.vec.b
+ wall_vec.y.b = this.edge
+ }
+ else if (this.side & BACK) {
+ wall_vec.x.a = this.vec.b
+ wall_vec.x.b = this.edge
+ wall_vec.y.a = this.vec.a
+ wall_vec.y.b = this.edge
+ }
+ return wall_vec
+ }
Wall.prototype.reset = function(){
}
diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css
index 6e42050..94430dd 100755
--- a/public/assets/stylesheets/app.css
+++ b/public/assets/stylesheets/app.css
@@ -71,10 +71,10 @@ a{
left: 0;
z-index: 6;
}
-#header.black .logo:hover {
+.desktop #header.black .logo:hover {
background: white;
}
-#header.black .logo:hover path {
+.desktop #header.black .logo:hover path {
fill: black;
}
#header.black path {
@@ -83,11 +83,11 @@ a{
#header.black .topLinks a {
color: white;
}
-#header.black .topLinks a:hover {
+.desktop #header.black .topLinks a:hover {
color: black;
background-color: white;
}
-#header.black a#help-button:hover {
+.desktop #header.black a#help-button:hover {
background-color: transparent;
text-shadow: 0 0 3px #fff, 0 0 3px #fff, 0 0 3px #fff, 0 0 3px #fff, 0 0 3px #fff;
}
@@ -135,7 +135,7 @@ a{
color:#444;
}
-.videoModal .ion-ios7-close-empty:hover {
+.desktop .videoModal .ion-ios7-close-empty:hover {
color:black;
}
@@ -175,7 +175,7 @@ a{
animation:1s redpulse infinite linear;
}
.topLinks a.ion-help-circled.active,
-.topLinks a.ion-help-circled:hover {
+.desktop .topLinks a.ion-help-circled:hover {
background:transparent;
color:red;
}
@@ -435,7 +435,7 @@ iframe.embed {
background-size: contain;
background-position: center;
}
-.projectList a:hover .room .mask {
+.desktop .projectList a:hover .room .mask {
background-color: rgba(128,128,128,0.1);
}
.room .images {
@@ -522,12 +522,12 @@ iframe.embed {
letter-spacing: 0.3px;
}
-.page .room .holder a:hover {
+.desktop .page .room .holder a:hover {
background:black;
color:white;
}
-.projectList a:hover label {
+.desktop .projectList a:hover label {
background:black;
color:white;
}
@@ -624,7 +624,7 @@ iframe.embed {
font-size: 13px;
}
-.footer a:hover{
+.desktop .footer a:hover{
text-decoration:underline;
}
@@ -679,7 +679,7 @@ iframe.embed {
.page .topLinks a:last-child {
border-right:0px solid;
}
-.topLinks a:hover {
+.desktop .topLinks a:hover {
background: black;
color: white;
}
@@ -696,7 +696,7 @@ iframe.embed {
background:white!important;
}
-.profilepage .bio a:hover {
+.desktop .profilepage .bio a:hover {
text-decoration:underline;
}
@@ -780,7 +780,7 @@ iframe.embed {
padding: 10px;
font-size: 18px;
}
-.profilepage .about h2 .btn:hover {
+.desktop .profilepage .about h2 .btn:hover {
background:black;
color:white;
}
@@ -838,7 +838,7 @@ border-left: 1px solid black;
}
-.templates span:hover .image {
+.desktop .templates span:hover .image {
background-color: #f00;
cursor:pointer;
}
@@ -1040,10 +1040,10 @@ border-left: 1px solid black;
padding:6px 8px 9px 8px;
}
-.logo:hover {
+.desktop .logo:hover {
background:black;
}
-.logo:hover svg {
+.desktop .logo:hover svg {
fill:white;
}
.profile{
@@ -1393,24 +1393,6 @@ border-left: 1px solid black;
z-index: 4;
}
-.editBtn{
- color: red;
- padding: 3px;
- font-size: 12px;
- display: inline-block;
- cursor:pointer;
- font-weight:600;
- text-decoration:none;
- position: absolute;
- right: 10px;
- top: 10px;
-}
-
-.editBtn:hover {
- background:red;
- color:white;
-}
-
.deleteArmed .mediaDrawer h3 {
background:#FF3B30;
color:white;
@@ -2444,7 +2426,7 @@ a[data-role="forgot-password"] {
}
.aboutRoom h1 {
- font-size:28px;
+ font-size:26px;
}
.txt {
font-size:12px;
@@ -2467,6 +2449,7 @@ a[data-role="forgot-password"] {
.aboutRoom h1 a{
text-decoration: none;
font-style: italic;
+ font-weight:500;
}
.desktop .aboutRoom h1 a:hover {
@@ -2698,7 +2681,7 @@ a[data-role="forgot-password"] {
height: 180px;
width: 50%;
display: inline-block;
- padding-top: 20px;
+ padding-top: 40px;
}
.profilePic {
diff --git a/public/assets/test/intersect3.html b/public/assets/test/intersect3.html
index 4fec891..5440a76 100644
--- a/public/assets/test/intersect3.html
+++ b/public/assets/test/intersect3.html
@@ -35,7 +35,7 @@ var scene = new MX.Scene()
var w = canvas.width = window.innerWidth
var h = canvas.height = window.innerHeight
-var cursor = new Rect( 150, 250, 150, 250 )
+var cursor = new Rect( new vec2(400, 200), new vec2(800, 500) )
var wall_vec = new Rect ( 0, 0, 0, 0 )
var points = [ cursor.x, cursor.y ]
@@ -67,10 +67,9 @@ Rooms.clipper.update()
Rooms.builder.build()
Rooms.grouper.build()
-var r = 4
+var r = 6
var intersect = new vec2 ()
-var intersects = []
var dragging = false, dragging_a, dragging_b
var delta = new vec2( 0, 0 )
@@ -102,7 +101,7 @@ var mymouse = new mouse({
},
})
-function draw () {
+function draw (time) {
ctx.fillStyle = "#fff"
ctx.fillRect(0,0,w,h)
@@ -115,28 +114,23 @@ function draw () {
points.forEach(drawPoint)
drawLine(cursor.x, cursor.y, "#f00")
- hud.innerHTML = ""
- intersects.length = 0
-
+// hud.innerHTML = ""
+ var closest_intersect, t, min_t = 1
+ var cursor_copy = cursor.extend_ends(scene.camera.radius)
+
+ hud.innerHTML = cursor_copy.x
+ drawPoint(cursor_copy.x, "#ff0")
+
Walls.list.forEach(function(wall, i){
- if (wall.side & LEFT_RIGHT) {
- wall_vec.x.a = wall.edge
- wall_vec.x.b = wall.vec.a
- wall_vec.y.a = wall.edge
- wall_vec.y.b = wall.vec.b
- }
- else {
- wall_vec.x.a = wall.vec.a
- wall_vec.x.b = wall.edge
- wall_vec.y.a = wall.vec.b
- wall_vec.y.b = wall.edge
- }
- drawLine(wall_vec.x, wall_vec.y, "#888", true)
- drawLine(origins.x, origins.y, "rgba(0,0,0,0.1)")
+ wall.get_points(wall_vec)
+ drawLine(wall_vec.x, wall_vec.y, "#088")
- var t = perp(origins, wall_vec) / ( perp(cursor, wall_vec) || 0.0000001 )
- intersect.a = cursor.x.a + ( cursor.y.a - cursor.x.a ) * t
- intersect.b = cursor.x.b + ( cursor.y.b - cursor.x.b ) * t
+ origins.x = cursor_copy.x
+ origins.y = wall_vec.x
+
+ t = perp(origins, wall_vec) / ( perp(cursor_copy, wall_vec) || 0.0000001 )
+ intersect.a = cursor_copy.x.a + ( cursor_copy.y.a - cursor_copy.x.a ) * t
+ intersect.b = cursor_copy.x.b + ( cursor_copy.y.b - cursor_copy.x.b ) * t
var collinear = is_collinear( intersect, wall_vec )
var long_enough_to_intersect = 0 <= t && t <= 1
@@ -168,20 +162,72 @@ function draw () {
}
drawPoint(intersect)
- if (intersecting_face) {
- hud.innerHTML += intersecting_face.y.a + "<br>"
- var clone = intersect.clone()
- clone.t = t
- intersects.push( clone )
+ if (actually_intersects && t < min_t) {
+ min_t = t
+ closest_intersect = intersect.clone()
+ closest_wall = wall_vec.clone()
}
})
- if (intersects.length) {
- // get the intersect with smallest T value
- // get the angle of the cam/pos vector
- // move the desired position to pos - 20px
- // display this point
+ if (closest_intersect) {
+ var a = angle(closest_wall)
+ wall_vec.assign(closest_wall)
+ wall_vec.x.a -= scene.camera.radius * sin(a)
+ wall_vec.x.b += scene.camera.radius * cos(a)
+ wall_vec.y.a -= scene.camera.radius * sin(a)
+ wall_vec.y.b += scene.camera.radius * cos(a)
+
+ drawLine(wall_vec.x, wall_vec.y, "rgba(0,255,255,1.0)")
+
+ origins.x = cursor.x
+ origins.y = wall_vec.x
+
+ var new_t = perp(origins, wall_vec) / ( perp(cursor, wall_vec) || 0.0000001 )
+ var wall_t = perp(origins, cursor) / ( perp(wall_vec, cursor) || 0.0000001 )
+
+ var closest_intersect2 = new vec2 ()
+ closest_intersect2.a = cursor.x.a + ( cursor.y.a - cursor.x.a ) * new_t
+ closest_intersect2.b = cursor.x.b + ( cursor.y.b - cursor.x.b ) * new_t
+
+ ctx.fillStyle = "#0ff"
+ drawPoint(closest_intersect2)
+ drawLine(cursor.x, closest_intersect2, "#00f")
+
+ var len = sqrt(dot(wall_vec, wall_vec))
+
+ // here compare len to the length of the wall in the direction we are travelling
+ var aw = angle(closest_wall)
+ var dd = dot2(diff(closest_wall), diff(cursor))
+
+// hud.innerHTML += " " + dd + " " + round(deg(aw))
+ if (dd > 0) {
+ len *= 1-abs(wall_t)
+ }
+ else {
+ len *= abs(wall_t)
+ aw += PI
+ }
+
+ len = clamp(len, 0, (1-min_t) * sqrt(dot(cursor, cursor)))
+
+// hud.innerHTML = [ aw ].map(function(n){ return round(deg(n)) })
+// hud.innerHTML += "__&nbsp;" + (dd > 0 ? "gt": "lt") + " " + round(len) + " " + (1-min_t) + " " + round((1-min_t)*sqrt(dot2(diff(cursor), diff(cursor))))
+
+ var end_of_ray = closest_intersect2.clone()
+ end_of_ray.a += len * cos(aw)
+ end_of_ray.b += len * sin(aw)
+
+ wall_vec.normalize()
+ end_of_ray.a = clamp(end_of_ray.a, wall_vec.x.a, wall_vec.y.a)
+ end_of_ray.b = clamp(end_of_ray.b, wall_vec.x.b, wall_vec.y.b)
+
+ drawPoint(end_of_ray)
+ drawLine(closest_intersect2, end_of_ray, "#00f")
}
+ else {
+// hud.innerHTML = [ (angle(cursor) + TWO_PI) % TWO_PI ].map(function(n){ return round(deg(n)) })
+ }
+
}
function drawLine (pa, pb, color, headless) {
ctx.fillStyle = color
@@ -192,11 +238,32 @@ function drawLine (pa, pb, color, headless) {
var y2 = pb.b
drawArrow(ctx, x1, y1, x2, y2, 3, headless ? 0 : 1)
}
-function drawPoint (p) {
+function drawPoint (p, color) {
+ if (color) {
+ ctx.fillStyle = color
+ }
var x = p.a - r
var y = p.b - r
ctx.fillRect(x, y, r*2, r*2)
}
+function angle (va) {
+ return atan2(va.y.b - va.x.b, va.y.a - va.x.a)
+}
+function angle2 (pa, pb) {
+ return atan2(pb.b - pa.b, pb.a - pa.a)
+}
+function normal (va) {
+ return atan2(va.x.a - va.y.a, va.y.b - va.x.b)
+}
+function dot (va, vb) {
+ return (va.y.a - va.x.a) * (vb.y.a - vb.x.a) + (va.y.b - va.x.b) * (vb.y.b - vb.x.b)
+}
+function diff (v) {
+ return new vec2(v.y.a - v.x.a, v.y.b - v.x.b)
+}
+function dot2 (pa, pb) {
+ return pa.a * pb.a + pa.b * pb.b
+}
function perp (va, vb) {
return (va.y.a - va.x.a) * (vb.y.b - vb.x.b) - (va.y.b - va.x.b) * (vb.y.a - vb.x.a)
}
@@ -220,10 +287,31 @@ function is_collinear (p, vec) {
return !! (on_x && on_y)
}
-
-function animate(){
+cursor.extend_ends = function(n){
+ var a = angle(this)
+ var clone = this.clone()
+ clone.x.a -= n*cos(a)
+ clone.x.b -= n*sin(a)
+ clone.y.a += n*cos(a)
+ clone.y.b += n*sin(a)
+ return clone
+}
+wall_vec.normalize = function(){
+ var carry
+ if (this.x.a > this.y.a) {
+ carry = this.x.a
+ this.x.a = this.y.a
+ this.y.a = carry
+ }
+ if (this.x.b > this.y.b) {
+ carry = this.x.b
+ this.x.b = this.y.b
+ this.y.b = carry
+ }
+}
+function animate(time){
requestAnimationFrame(animate)
- draw()
+ draw(time)
}
animate()