Ok, I have two positions in 3d space:
var fromX = 1,
fromY = 2,
fromZ = 3,
toX = 15,
toY = 16,
toZ = 17;
Then I need to calculate the current position, when someone/something is moving in a straight line from the from-coordinates, to the to-coordinates. I know the distance left is 2, what would be the formula for calculating the current position?
I guess this is more of a math question than a javascript question, but it is for a javascript application, so I'm hoping that is not a problem.
Given two points, fromPt and toPt, the distance between two points can easily be calculated:
distanceX = Math.pow(fromPt.x - toPt.x, 2)
distanceY = Math.pow(fromPt.y - toPt.y, 2)
distanceZ = Math.pow(fromPt.z - toPt.z, 2)
total_distance = Math.sqrt(distanceX + distanceY + distanceZ)
and now finding the correct point along the line is just a case of correct interpolation :)
newPt = {}
newPt.x = fromPt.x + ((toPt.x - fromPt.x) * (wantedDistance / total_distance))
newPt.y = fromPt.y + ((toPt.y - fromPt.y) * (wantedDistance / total_distance))
newPt.z = fromPt.z + ((toPt.z - fromPt.z) * (wantedDistance / total_distance))
There are already 2 answers with the correct algorithm, this one's no different, just a bit neater.
// Distance between two points is the square root of the sum
// of the squares of the differences
function get3dDistance(startCoords, endCoords) {
var dx = Math.pow((startCoords[0] - endCoords[0]), 2);
var dy = Math.pow((startCoords[1] - endCoords[1]), 2);
var dz = Math.pow((startCoords[2] - endCoords[2]), 2);
return Math.sqrt(dx + dy + dz);
}
// The coordinates of a point some distance from the end is
// proportional to the distance left and total distance.
function getCoordsFromDistanceLeft(startCoords, endCoords, distanceLeft) {
var distance = get3dDistance(startCoords, endCoords);
var f = (distance - distanceLeft)/distance;
return [startCoords[0] + f*(endCoords[0] - startCoords[0]),
startCoords[1] + f*(endCoords[1] - startCoords[1]),
startCoords[2] + f*(endCoords[2] - startCoords[2])];
}
// Test case
var start = [1,2,3];
var end = [15,16,17];
var distanceLeft = 2;
// Distance between the two points
var dist = get3dDistance(start, end)
document.write('distance: ' + dist + '<br>');
// distance: 24.24871130596428
// Get the coords
var x = getCoordsFromDistanceLeft(start, end, distanceLeft);
document.write('x: ' + x + ' is ' + distanceLeft + ' to end<br>');
// x: 13.845299461620748,14.845299461620748,15.845299461620748 is 2 to end
document.write('From x to end: ' + get3dDistance(x, end) + '<br>');
// From x to end: 2.0000000000000013
Salix alba has introduced Math.hypot, which is interesting but since it's a new feature in ECMAScript 2015 it would be wise to include a polyfill.
You need to use 3D Pythagoras to find the distance between two points. If x1,y1,z1 and x2,y2,z2 are your points then the distance is sqrt((x1-x2)^2+(y1-y2)^2+(z1-z2)^2). There are several ways of finding the desired point. We can find the distance from the starting point to the ending point and then calculate the proportion of that distance which will give 2 as a result using linear interpolation.
var fromX = 1,
fromY = 2,
fromZ = 3,
toX = 15,
toY = 16,
toZ = 17;
// find the difference
var dx = toX-fromX, dy = toY-fromY, dz=toZ-fromZ;
// find the total length
var dist = Math.hypot(dx,dy,dz);
// find the proportion of this length
var lambda = (dist-2.0) / dist;
// do the linear interpolation
var x = fromX + lambda * dx,
y = fromY + lambda * dy,
z = fromZ + lambda * dz;
console.log(x,y,z);
// Just to check
var dx2 = toX-x, dy2 = toY-y, dz2=toZ-z;
var dist2 = Math.hypot(dx2,dy2,dz2);
console.log(dist2);
We get the result 13.845299461620748 14.845299461620748 15.845299461620748 and the final distance is 2.0000000000000013.
Note I've uses Math.hypot this is a new feature which works in Chrome/firefox/opera but not in IE. There is a work-around to enable it in other browsers if needed. You just use Math.sqrt(dx*dx+dy*dy+dz*dz) instead.
Related
I looked around and I couldn't find any info on the topic... probably because I can't iterate my problem accurately into a search engine.
I'm trying to take raw line data from a dxf, sort it into squares, find the center of each square, number the center, and print the result to pdf.
I have a data structure similar to the following:
[
[{x: 50, y:50}, {x:52, y:52}],
[{x: 52, y:52}, {x:54, y:54}],
[{x: 54, y:54}, {x:56, y:56}]...
]
These coordinates are obtained from parsing a dxf using dxf-parser, which returns an array of objects that describe the path of the line. Four of these combine to make a square, which I segment using
function chunkArrayInGroups(arr, size) {
let result = [];
let pos = 0;
while (pos < arr.length) {
result.push(arr.slice(pos, pos + size));
pos += size;
}
return result;
}
((Size = 4))
This behaves as intended for the most part, except these coordinates were created with the origin in the center of the screen. The pdf library I'm using to create the final document does not use the same coordinate system. I believe it starts the origin at the top left of the page. This made all of my negative values ((Anything to the left of the center of the model)) cut off the page.
To remedy this, I iterate through the array and collect '0 - all x and y values' in a new array, which I find the max of to give me my offset. I add this offset to my x values before plugging them into my pdf creator to draw the lines.
I'm not sure what is causing it, but the output is 'Da Vinci Style' as I like to call it, it's rotated 180 degrees and written backwards. I thought adding some value to each cell would fix the negative issue... and it did, but the data is still with respect to a central origin. Is there a way I can redefine this data to work with this library, or is there some other library where I can graph this data and also add text at specific spots as my case dictates. I would like to continue to use this library as I use it for other parts of my program, but I am open to new and more efficient ideas.
I appreciate your time and expertise!
What it's supposed to look like
Source Picture
"Da Vinci'fied" Result
Current Output
Copy of the code:
const PDFDocument = require('pdfkit');
const doc = new PDFDocument({ autoFirstPage: true })
const DxfParser = require('dxf-parser')
let fileText = fs.readFileSync('fulltest.dxf', { encoding: 'utf-8' })
let data = []
let data2 = []
let data3 = []
let shiftx = []
let shifty = []
let factor = 5
var parser = new DxfParser();
let i = 0
doc.pipe(fs.createWriteStream('test.pdf'));
try {
var dxf = parser.parseSync(fileText);
let array = dxf.entities
array.forEach(line => {
if (line.layer === "Modules") {
data.push(line.vertices)
}
if (line.layer === "Buildings") {
data2.push(line.vertices)
}
if (line.layer === "Setbacks") {
data3.push(line.vertices)
}
let segment = line.vertices
segment.forEach(point => {
shiftx.push(0 - point.x)
shifty.push(0 - point.y)
})
})
let shift = biggestNumberInArray(shiftx)
console.log(shift)
data = chunkArrayInGroups(data, 4)
data.forEach(module => {
let midx = []
let midy = []
module.forEach(line => {
let oldx = (line[1].x + shift) * factor
let oldy = (line[1].y + shift) * factor
let newx = (line[0].x + shift) * factor
let newy = (line[0].y + shift) * factor
doc
.moveTo(oldx, oldy)
.lineTo(newx, newy)
.stroke()
midx.push(oldx + (newx - oldx) / 2)
midy.push(oldy + (newy - oldy) / 2)
})
let centerx = (midx[0] + (midx[2] - midx[0]) / 2)
let centery = (midy[0] + (midy[2] - midy[0]) / 2)
let z = (i + 1).toString()
doc
.fontSize(10)
.text(z, centerx-5, centery-5)
i++
})
data2.forEach(line => {
let oldx = (line[0].x + shift) * factor
let oldy = (line[0].y + shift) * factor
let newx = (line[1].x + shift) * factor
let newy = (line[1].y + shift) * factor
doc
.moveTo(oldx, oldy)
.lineTo(newx, newy)
.stroke()
})
data3.forEach(line => {
let oldx = (line[0].x + shift) * factor
let oldy = (line[0].y + shift) * factor
let newx = (line[1].x + shift) * factor
let newy = (line[1].y + shift) * factor
doc
.moveTo(oldx, oldy)
.lineTo(newx, newy)
.stroke('red')
})
doc.end();
} catch (err) {
return console.error(err.stack);
}
function biggestNumberInArray(arr) {
const max = Math.max(...arr);
return max;
}
function chunkArrayInGroups(arr, size) {
let result = [];
let pos = 0;
while (pos < arr.length) {
result.push(arr.slice(pos, pos + size));
pos += size;
}
return result;
}
After sitting outside and staring at the fence for a bit, I revisited my computer and looked at the output again. I rotated it 180 as I did before, and studied it. Then I imagined it flipped over the y axis, like right off my computer. THAT WAS IT! I grabbed some paper and drew out the original coordinates, and the coordinates the pdf library.
input coords ^ >
output coords v >
I realized the only difference in the coordinate systems was that the y axis was inverted! Changing the lines to
let oldx = (line[1].x + shift) * factor
let oldy = (-line[1].y + shift) * factor
let newx = (line[0].x + shift) * factor
let newy = (-line[0].y + shift) * factor
inverted with respect to y and after the shift, printed correctly! Math wins again hahaha
I've been trying to implement collision detection between circles and polygons based on Randy Gaul's C++ Impulse Engine, following the code pretty closely, but the algorithm never returns true.
Here's the JSFiddle. (the bodies are rendered using the HTML5 Canvas API for convenience)
A snippet of the code (just collision detection):
const circPoly = (a, b) => {
let data = {},
center = a.pos;
data.contacts = [];
center = b.mat.clone().trans().mult(center.clone().sub(b.pos));
let sep = -Number.MAX_VALUE,
faceNorm = 0;
for (let i = 0; i < b.verts2.length; ++i) {
let sep2 = b.norms[i].dot(center.clone().sub(b.verts2[i]));
if (sep2 > a.radius) return data;
if (sep2 > sep) { sep = sep2; faceNorm = i; }
}
let v1 = b.verts2[faceNorm],
v2 = b.verts2[faceNorm + 1 < b.verts2.length ? faceNorm + 1 : 0];
if (sep < 0.0001) {
data.depth = a.radius;
data.norm = b.mat.clone().mult(b.norms[faceNorm]).neg();
data.contacts[0] = data.norm.clone().vmult(a.pos.clone().sadd(a.radius));
return data;
}
let dot1 = center.clone().sub(v1).dot(v2.clone().sub(v1)),
dot2 = center.clone().sub(v2).dot(v1.clone().sub(v2));
data.depth = a.radius - sep;
if (dot1 <= 0) {
if (center.dist2(v1) > a.radius * a.radius) return data;
let norm = v1.clone().sub(center);
norm = b.mat.clone().mult(norm);
norm.norm();
data.norm = norm;
v1 = b.mat.clone().mult(v1.clone().add(b.pos));
data.contacts[0] = v1;
} else if (dot2 <= 0) {
if (center.dist2(v2) > a.radius * a.radius) return data;
let norm = v2.clone().sub(center);
norm = b.mat.clone().mult(norm);
norm.norm();
data.norm = norm;
v2 = b.mat.clone().mult(v2.clone().add(b.pos));
data.contacts[0] = v2;
} else {
let norm = b.norms[faceNorm];
if (center.clone().sub(v1).dot(norm) > a.radius) return data;
norm = b.mat.clone().mult(norm);
data.norm = norm.clone().neg();
data.contacts[0] = data.norm.clone().vmult(a.pos.clone().sadd(a.radius));
}
return data;
};
Note that b.verts2 refers to the polygon's vertices in real world coordinates.
I know for a fact that there are no problems with the Vector class but as I don't exactly have very much experience with transformation matrices, that class could be the root of these errors, although the code for it is pretty much entirely derived from the Impulse Engine as well, so it should work. As mentioned before, the algorithm always returns false, even when a collision really has occurred. What am I doing wrong here? I tried taking out the early returns, but that just returns weird results like contact points with negative coordinates which obviously is not quite correct.
EDIT: Modified my vector class's perpendicular function to work the same way as the Impulse Engine's (both ways are right, but I think one is clockwise and the other one counterclockwise -- I also modified my vertices to reflect the counterclockwise-ness). Unfortunately, it still fails the test.
https://jsfiddle.net/khanfused/tv359kgL/4/
Well the are many problems and I really dont understand what you are trying to do as it seem overly complex. Eg why does matrix have trans??? and why are you using the Y up screen as the coordinate system for the transform??? (rhetorical)
In the first loop.
The first is that you are testing the distance of the normal vectors
of each vert, should be testing the vert position.
Also you are finding the distance using the vec.dot function that
returns the square of the distance. But you test for the radius, you
should be testing for if(sep2 < radius * radius)
And you have the comparison the wrong way around you should be
testing if less than radius squared (not greater than)
Then when you do detect a vert within the radius you return the data
object but forget to put the vert that was found inside the circle on
the data.contacts array.
I am not sure what the intention of keeping the index of the most
distant vect is but then the rest of the function make zero sense to
me???? :( and I have tried to understand it.
All you need to do is
A check if any verts on the poly are closer than radius, if so then you have a intercept (or is completely inside)
Then you need to check the distance of each line segment
Can be done for each line segment with the following if you dont need the intercepts (or below that if you need intercepts) only use one or the other.
// circle is a point {x:?,y:?}
// radius = is the you know what
// p1,p2 are the start and end points of a line
checkLineCircle = function(circle,radius,p1,p2){
var v1 = {};
var v2 = {};
var v3 = {};
var u;
// get dist to end of line
v2.x = circle.x - p1.x;
v2.y = circle.y - p1.y;
// check if end points are inside the circle
if( Math.min(
Math.hypot(p2.x - circle.x, p2.y - circle.y),
Math.hypot(v2.x, v2.y)
) <= radius){
return true;
}
// get the line as a vector
v1.x = p2.x - p1.x;
v1.y = p2.y - p1.y;
// get the unit distance of the closest point on the line
u = (v2.x * v1.x + v2.y * v1.y)/(v1.y * v1.y + v1.x * v1.x);
// is this on the line segment
if(u >= 0 && u <= 1){
v3.x = v1.x * u; // get the point on the line segment
v3.y = v1.y * u;
// get the distance to that point and return true or false depending on the
// it being inside the circle
return (Math.hypot(v3.y - v2.y, v3.x - v2.x) <= radius);
}
return false; // no intercept
}
Do that for each line.To save time transform the circle center to the polygon local, rather than transform each point on the poly.
If you need the points of intercept then use the following function
// p1,p2 are the start and end points of a line
// returns an array empty if no points found or one or two points depending on the number of intercepts found
// If two points found the first point in the array is the point closest to the line start (p1)
function circleLineIntercept(circle,radius,p1,p2){
var v1 = {};
var v2 = {};
var ret = [];
var u1,u2,b,c,d;
// line as vector
v1.x = p2.x - p1.x;
v1.y = p2.y - p1.y;
// vector to circle center
v2.x = p1.x - circle.x;
v2.y = p1.y - circle.y;
// dot of line and circle
b = (v1.x * v2.x + v1.y * v2.y) * -2;
// length of line squared * 2
c = 2 * (v1.x * v1.x + v1.y * v1.y);
// some math to solve the two triangles made by the intercept points, the circle center and the perpendicular line to the line.
d = Math.sqrt(b * b - 2 * c * (v2.x * v2.x + v2.y * v2.y - radius * radius));
// will give a NaN if no solution
if(isNaN(d)){ // no intercept
return ret;
}
// get the unit distance of each intercept to the line
u1 = (b - d) / c;
u2 = (b + d) / c;
// check the intercept is on the line segment
if(u1 <= 1 && u1 >= 0){
ret.push({x:line.p1.x + v1.x * u1, y : line.p1.y + v1.y * u1 });
}
// check the intercept is on the line segment
if(u2 <= 1 && u2 >= 0){
ret.push({x:line.p1.x + v1.x * u2, y : line.p1.y + v1.y * u2});
}
return ret;
}
I will leave it up to you to do the polygon iteration.
Please bear with me. I appreciate any pointers / patience and help in understanding the code pasted below.
All the lines marked with the '// ??' comment is where I don't have a clue what's happening.
I picked up the Building an HTML5 Game book (http://buildanhtml5game.com/) in the hopes of learning how to write a game, more especially in HTML5 and JavaScript.
To my surprise, the book does not really explain various background information or assumes the readers already know their way around.
I am not a mathematics expert and that's one big reason I am stuck with the code below. The book barely touches the surface and the explanation is in a line or two (leaving me more confused).
Please, I may ask, do provide me with links so I study the mathematics behind the formulas below and write some English explanation as well so I understand.
I don't want to skip the mathematics parts in this book because it defeats the purpose.
Much appreciated.
var BubbleShoot = window.BubbleShoot || {};
BubbleShoot.CollisionDetector = (function($){
var CollisionDetector = {
findIntersection : function(curBubble,board,angle) {
// 'angle' is the angle between the 'curBubble' starting bubble
// at the center of the screen and the mouse click's direction aimed at the bubbles
// above.
// I understand how that angle is computed in previous code snippets.
// 'board' contains an array of bubble objects that are static and laid up on the board
// waiting to be shot at with 'curbubble' and 'angle'.
// Get the bubble rows container
var rows = board.getRows();
var collision = null;
// Get the bubble's that will be shot from the center coordinates
var pos = curBubble.getSprite().position();
// The start coordinates are the bubble's center
var start = {
left : pos.left + BubbleShoot.ui.BUBBLE_DIMS/2,
top : pos.top + BubbleShoot.ui.BUBBLE_DIMS/2
};
// ?? (A) what does this give us (mathematically speaking, what are those variables called)
var dx = Math.sin(angle);
var dy = -Math.cos(angle);
for(var i=0;i<rows.length;i++){
// for each row
var row = rows[i];
for(var j=0;j<row.length;j++){
// Get bubble at i,j
var bubble = row[j];
if(bubble){
// Get bubble's coordinates. we want to see if the starting bubble
// will collidate with this static bubble if the starting bubble was fired
// with an angle 'angle'
var coords = bubble.getCoords();
// ?? (B) that's not the distance between the two points!
// ?? what do you call this mathematically?
var distToBubble = {
x : start.left - coords.left,
y : start.top - coords.top
};
// ?? (C) what is 't'? what does it give? can you please give me reference
// ?? so I study the proper math behind its purpose?
var t = dx * distToBubble.x + dy * distToBubble.y;
// ?? (D) why '-t' * dx and what does this give us?
var ex = -t * dx + start.left;
// ?? (E) same for 'ey'
var ey = -t * dy + start.top;
// distance between the two points (ex,ey) and (coords.left,coords.top)
// ?? (F) I am not sure what are 'ex' and 'ey'
var distEC = Math.sqrt((ex - coords.left) * (ex - coords.left) +
(ey - coords.top) * (ey - coords.top));
if(distEC<BubbleShoot.ui.BUBBLE_DIMS * .75){
// ?? (G) dt is what?
var dt = Math.sqrt(BubbleShoot.ui.BUBBLE_DIMS * BubbleShoot.
ui.BUBBLE_DIMS - distEC * distEC);
// ?? (H) what's this?
var offset1 = {
x : (t - dt) * dx,
y : -(t - dt) * dy
};
// ?? (I) and this?!
var offset2 = {
x : (t + dt) * dx,
y : -(t + dt) * dy
};
// ?? (J) distance between something
var distToCollision1 = Math.sqrt(offset1.x * offset1.x +
offset1.y * offset1.y);
var distToCollision2 = Math.sqrt(offset2.x * offset2.x +
offset2.y * offset2.y);
if(distToCollision1 < distToCollision2){
var distToCollision = distToCollision1;
var dest = {
x : offset1.x + start.left,
y : offset1.y + start.top
};
}else{
var distToCollision = distToCollision2;
var dest = {
x : -offset2.x + start.left,
y : offset2.y + start.top
};
}
if(!collision || collision.distToCollision>distToCollision){
collision = {
bubble : bubble,
distToCollision : distToCollision,
coords : dest
};
};
};
};
};
};
return collision;
}
};
return CollisionDetector;
})(jQuery);
You can play the game here just to see how it looks: http://buildanhtml5game.com/?page_id=20
As part of a word cloud rendering algorithm (inspired by this question), I created a Javascript / Processing.js function that moves a rectangle of a word along an ever increasing spiral, until there is no collision anymore with previously placed words. It works, yet I'm uncomfortable with the code quality.
So my question is: How can I restructure this code to be:
readable + understandable
fast (not doing useless calculations)
elegant (using few lines of code)
I would also appreciate any hints to best practices for programming with a lot of calculations.
Rectangle moveWordRect(wordRect){
// Perform a spiral movement from center
// using the archimedean spiral and polar coordinates
// equation: r = a + b * phi
// Calculate mid of rect
var midX = wordRect.x1 + (wordRect.x2 - wordRect.x1)/2.0;
var midY = wordRect.y1 + (wordRect.y2 - wordRect.y1)/2.0;
// Calculate radius from center
var r = sqrt(sq(midX - width/2.0) + sq(midY - height/2.0));
// Set a fixed spiral width: Distance between successive turns
var b = 15;
// Determine current angle on spiral
var phi = r / b * 2.0 * PI;
// Increase that angle and calculate new radius
phi += 0.2;
r = (b * phi) / (2.0 * PI);
// Convert back to cartesian coordinates
var newMidX = r * cos(phi);
var newMidY = r * sin(phi);
// Shift back respective to mid
newMidX += width/2;
newMidY += height/2;
// Calculate movement
var moveX = newMidX - midX;
var moveY = newMidY - midY;
// Apply movement
wordRect.x1 += moveX;
wordRect.x2 += moveX;
wordRect.y1 += moveY;
wordRect.y2 += moveY;
return wordRect;
}
The quality of the underlying geometric algorithm is outside my area of expertise. However, on the quality of the code, I would say you could extract a lot of functions from it. Many of the lines that you have commented could be turned into separate functions, for example:
Calculate Midpoint of Rectangle
Calculate Radius
Determine Current Angle
Convert Polar to Cartesian Coodinates
You could consider using more descriptive variable names too. 'b' and 'r' require looking back up the code to see what they are for, but 'spiralWidth' and 'radius' do not.
In addition to Stephen's answer,
simplify these two lines:
var midX = wordRect.x1 + (wordRect.x2 - wordRect.x1)/2.0;
var midY = wordRect.y1 + (wordRect.y2 - wordRect.y1)/2.0;
The better statements:
var midX = (wordRect.x1 + wordRect.x2)/2.0;
var midY = (wordRect.y1 + wordRect.y2)/2.0;
I'm trying to change background RGB according to mouse position. Here you can see the example http://rockit.folio.su/gexans/
There are no problems with first two numbers, they are horizontal and vertical axes. But there is a problem with 3rd number which must be relative to the diagonal of the document. And I figured out that it's because i receive the number according to X and Y mouse position, but I need it according to how close the mouse is to the diagonal of the document and not a mouse-made rectangle.
Here is the code
function mousePage(e){
var x = 0, y = 0, z =0;
if (!e) e = window.event;
x = e.pageX;
y = e.pageY;
z = Math.sqrt(Math.pow(x,2) + Math.pow(y,2));
return {"x":x, "y":y, "z":z};
}
$(window).load(function(){
$(document).mousemove(function(e) {
var widthStep = $(document).width() / 256;
var heightStep = $(document).height() / 256;
var diagonalStep = Math.sqrt(Math.pow($(document).width(),2) + Math.pow($(document).height(),2)) / 256;
var mCur = mousePage(e);
var colorX = Math.floor( Number(mCur.x) / Number(widthStep) );
var colorY = Math.floor( Number(mCur.y) / Number(heightStep) );
var colorZ = Math.floor( Number(mCur.z) / Number(diagonalStep));
var hue = 'rgb(' + colorX + ',' + colorY + ',' + colorZ + ')';
$("body").css({backgroundColor: hue});
});
});
Ok, so now I have a formula for the distance from cursor to the line like this
var numerator = Math.abs( ( A * m ) + ( B * n ) + C );
var denominator = Math.sqrt( Math.pow( A, 2 ) + Math.pow( B, 2 ) );
var d = numerator / denominator;
And I suppose that now I need to calculate the distance to top right, divide it by 256 = dStep, then distance to top right - var d and divide it by dStep = mColorZ and after that colorZ - mColorZ = the value that I need for my third colour?
And what is even more important, I have no idea what are the values for A, B, and C.
z=x*y/oldz; //the distance close from mouse to the diagonal, is this u want?
I'm not sure if this is what I want. What does this formula do?)
Update
Right now I'm having this but it gives me Zero on the diagonal.
var width = $(document).width();
var height = $(document).height();
var widthStep = $(document).width()/256;
var heightStep = $(document).height()/256;
var diagonalStep = Math.sqrt(Math.pow(width,2)+Math.pow(height,2))/256;
var mCur = mousePage(e);
var numerator = Math.abs((height*Number(mCur.x))+(width*Number(mCur.y))+0);
var denominator = Math.sqrt(Math.pow(height,2)+Math.pow(width,2));
var d = numerator/denominator;
var vp_numerator = Math.abs((height*width)+(width*height)+0);
var vp_denominator = Math.sqrt(Math.pow(height,2)+Math.pow(width,2));
var vp_d = vp_numerator/vp_denominator;
var vp_dStep = vp_d/256;
var m_colorZ = Math.floor(Number(d)/Number(vp_dStep));
var colorX = Math.floor(Number(mCur.x)/Number(widthStep));
var colorY = Math.floor(Number(mCur.y)/Number(heightStep));
var colorZ = Math.floor(Number(mCur.z)/Number(diagonalStep)) - m_colorZ;
var hue = 'rgb(' + colorX + ',' + colorY + ',' + colorZ + ')';
$("body").css({backgroundColor: hue});
Update
Ok, it's great that I have now the distance of cursor from the diagonal line. But now I need to have position of cursor ON the diagonal, if it's top-right part of the screen it's vertical line from cursor crossing the diagonal reltive to X, lower-left - horizontal relative to Y.
And after that position on the line - distance from the line = color.
Update #2
I decided to finish it, but I got not the cool version but just a simple one. The third value always depends on hypotenuse. Very simple. Here's the code.
function rgbchange(target, source){
var widthStep = source.width() / 256,
heightStep = source.height() / 256,
diagonal = Math.sqrt( Math.pow( source.width(), 2 ) + Math.pow( source.height(), 2 ) ),
diagonalStep = diagonal / 256,
colorX,
colorY,
colorZ,
newDiagonal,
hue;
source.on('mousemove', function( event ){
colorX = Math.floor( event.pageX / widthStep ),
colorY = Math.floor( event.pageY / heightStep );
newDiagonal = Math.sqrt( Math.pow( event.pageY, 2 )+ Math.pow( event.pageX, 2 ) );
colorZ = 255 - Math.floor( ( diagonal - newDiagonal ) / diagonalStep );
hue = 'rgb(' + colorX + ',' + colorY + ',' + colorZ + ')';
target.css({'background-color': hue});
});
}
The example
z = Math.sqrt(Math.pow(x,2) + Math.pow(y,2));
This is saying that the value z is the length of the line between the mouse and the upper-left-hand corner. I'm not sure what you mean by "distance from the diagonal of the document", but if you really want the closest distance to the line which looks like this:
____
|\ .| <-- hypothetical point (.)
| \/ | <-- perpendicular line
| \ |
| \|
Then you can use the formula for the closest line to a plane (google for formula for distance of point from line).
var oldz=Math.sqrt(Math.pow(x,2) + Math.pow(y,2));
z=x*y/oldz; //the distance close from mouse to the diagonal, is this u want?