A few years ago I made a Javascript script for APNGedit to draw the Laughing Man logo. It used the now defunct mozTextAlongPath
I recently rediscovered this script and redid it using translations, rotations and fillText(). However, this doesn't respect character width nor is it kerned (it looks terrible).
Original circa 2009 (not perfect, but okay):
Current version:
How can I draw text in an arc on an HTML5 canvas and make it look good?
Solution Code based on Kolink's answer:
ctx.fillStyle = primaryColor;
ctx.font = fontSize + 'px ' + fontFamily;
var textWidth = ctx.measureText(text).width,
charRotation = 0,
character, charWidth, nextChar, nextWidth, bothWidth, kern, extraRotation, charSegment;
for (var i=0, l=text.length; i<l; i++) {
character = nextChar || text[i];
charWidth = nextWidth || ctx.measureText(character).width;
// Rotate so the letter base makes a circle segment instead of a tangent
extraRotation = (Math.PI/2) - Math.acos((charWidth/2) / radius);
ctx.save();
ctx.translate(radius, h/2);
ctx.rotate(charRotation);
ctx.translate(0, -textRadius);
ctx.rotate(extraRotation);
ctx.fillText(character,0,0);
ctx.restore();
nextChar = text[i+1] || '';
nextWidth = ctx.measureText(nextChar).width;
bothWidth = ctx.measureText(character+nextChar).width;
kern = bothWidth - charWidth - nextWidth;
charSegment = (charWidth+kern) / textWidth; // percent of total text size this takes up
charRotation += charSegment * (Math.PI*2);
}
Obviously, it is no difficulty to place letters on the arc itself (just align center bottom to the circle). However, as you noted, the problem is kerning.
Luckily, we have measureText(), which can tell us the width of the letters and therefore what kerning to use.
The circumference of your circle is simply 2πr, and total width of the text is ctx.measureText("Your text here");. Get the ratio of these two values and you will find out how much you need to space out or squash together your words.
You probably want to apply the spacing modifier to the words as a whole, rather than the individual letters. To do this, use measureText() on the sentence with spaces stripped to get the width of the letters (and by extension the total width of the spaces).
Now you need to plot where each word will go. Use measureText() again to find the width of each word and plot its center point on your circle, adding a portion of the total space value between each word. Now use measureText() on each individual letter and draw it in the right place to get perfect kerning.
All being well, you should have a perfectly spaced circle of text.
So measure text is good, what I ended up doing, was Math.pow(measureText + measureTextOfLastChar, 3 / 4)
for some reason, square root of the sum of the widths of the current and previous character made some spacings too skinny, and without a square root at all, makes it bad too, but Math.pow(sum, 3/4) for some reason creates a great ratio. Heres the code ( in coffeescript )
CanvasRenderingContext2D::fillTextCircle = (str, centerX, centerY, radius, angle) ->
len = str.length
s = undefined
#save()
#translate centerX, centerY
#rotate - (1 + 1 / len) * angle / 2
n = 0
prevWidth = 0
while n < len
thisWidth = #measureText(str[n]).width
#rotate angle / len * Math.pow(thisWidth + prevWidth, 3 / 4) / #measureText(str).width
s = str[n]
prevWidth = #measureText(str[n]).width
#fillText s, -#measureText(str[n]).width / 2, -1 * radius
n++
#restore()
then call it using
context.fillTextCircle('hiya world', halfWidth, halfHeight, 95, 26)
I was guessing and checking a bit, though I took calc 4 so I subconsciously knew what I was doing. Anyway, it produces perfect character spacing, that you couldn't get without Math.pow(sum_character_widths, 3/4)
Everything can be changed, except keep the Math.pow(sum, 3/4) in the loop, since that's the part I made better than the rest of the stuff I found online.
Related
I have a canvas of which i have drawn some white text on to.
I then get the canvas image data and run through each pixel checking if its white:
var pixelData =
this.ctx.getImageData(0,0,this.ctx.canvas.width,this.ctx.canvas.height);
for(var i = 0; i < pixelData.data.length;i+=4) //run through pixels
if(pixelData.data[i] == 255 && pixelData.data[i+1] == 255 && pixelData.data[i+2] == 255) //is white?
this.possiblePxs.push(i);
I read somewhere that "getImageData" returns a one dimensional array where the first element is is the red value of the first pixel, second is blue third is green and fourth is alpha
and so i increment the loop by 4 each iteration.
if a white pixel is found i store it in the "possiblePxs" array.
Later in my code i need to select one of these pixels and draw something at its location
and so first i create a new random index between 0 and the length of "possiblePxs":
var randomPx = Math.floor(Math.random()*this.possiblePxs.length)
Then, in order to get the x location i just take the result of the value of possiblePxs at that random index modulus the canvas height:
var randomX = this.possiblePxs[randomPx] % this.ctx.canvas.height
and i can then get the y location by subtracting randomX from the value of possiblePxs at the random index and divide it by the height of the canvas again:
var randomY = (this.possiblePxs[randomPx] - randomX ) / this.ctx.canvas.height;
However this doesn't seem to be working, when i then draw a rect at the location its nowhere near any of the white pixels on the canvas?
I must have messed up the math of either the loop or the finding x, y part. I was hoping maybe one of you guys could tell me what i did wrong and how to fix it :)
When you push the value of i, you should divide i by 4:
this.possiblePxs.push(i/4);
And the extraction of the X coordinate should be modulo the width not the height of the canvas:
var randomX = this.possiblePxs[randomPx] % this.ctx.canvas.width;
Similarly for the Y coordinate:
var randomY = (this.possiblePxs[randomPx] - randomX ) / this.ctx.canvas.width;
this is my first question after having relied on this site for years!
Anyway, I'd like to accomplish something similar to this effect:
http://www.flashmonkey.co.uk/html5/wave-physics/
But on a circular path, instead of a horizon. Essentially, a floating circle/blob in the center of the screen that would react to mouse interaction. What I'm not looking for is gravity, or for the circle to bounce around the screen - only surface ripples.
If at all possible I'd like to apply a static texture to the shape, is this a possibility? I'm completely new to Canvas!
I've already tried replacing some code from the above example with circular code from the following link, to very limited success:
http://www.html5canvastutorials.com/tutorials/html5-canvas-circles/
If only it were that easy :)
Any ideas?
Thanks in advance!
I tried to figure out how wave simulation works using View Source and JavaScript console. It's working fine but threw some JS errors. Also, it seems physics update is entangled with rendering in the render() method.
Here is what I found about the code:
The mouseMove() method creates disturbances on the wave based on mouse position, creating a peak around the mouse. The target variable is the index of the particle that needs to be updated, it's calculated from mouse pos.
if (particle && mouseY > particle.y) {
var speed = mouseY - storeY;
particles[target - 2].vy = speed / 6;
particles[target - 1].vy = speed / 5;
particles[target].vy = speed / 3;
particles[target + 1].vy = speed / 5;
particles[target + 2].vy = speed / 6;
storeY = mouseY;
}
Then, the particles around target are updated. The problem I found is that it does no bounds checking, i.e. it can potentially particles[-1] when target == 0. If that happens, an exception is thrown, the method call ends, but the code does not stop.
The render() method first updates the particle positions, then renders the wave.
Here is its physics code:
for (var u = particles.length - 1; u >= 0; --u) {
var fExtensionY = 0;
var fForceY = 0;
if (u > 0) {
fExtensionY = particles[u - 1].y - particles[u].y - springs[u - 1].iLengthY;
fForceY += -fK * fExtensionY;
}
if (u < particles.length - 1) {
fExtensionY = particles[u].y - particles[u + 1].y - springs[u].iLengthY;
fForceY += fK * fExtensionY;
}
fExtensionY = particles[u].y - particles[u].origY;
fForceY += fK / 15 * fExtensionY;
particles[u].ay = -fForceY / particles[u].mass;
particles[u].vy += particles[u].ay;
particles[u].ypos += particles[u].vy;
particles[u].vy /= 1.04;
}
Basically, it's Hooke's Law for a chain of particles linked by springs between them. For each particle u, it adds the attraction to the previous and next particles (the if statements check if they are available), to the variable fForceY. I don't fully understand the purpose of the springs array.
In the last four lines, it calculates the acceleration (force / mass), updates the velocity (add acceleration), then position (add velocity), and finally, reduce velocity by 1.04 (friction).
After the physics update, the code renders the wave:
context.clearRect(0, 0, stageWidth, stageHeight);
context.fillStyle = color;
context.beginPath();
for (u = 0; u < particles.length; u++) {
...
}
...
context.closePath();
context.fill();
I'm not explaining that, you need to read a canvas tutorial to understand it.
Here are some ideas to get started, note that I didn't test these code.
To modify the code to draw a circular wave, we need introduce a polar coordinate system, where the particle's x-position is the angle in the circle and y-position the distance from center. We should use theta and r here but it requires a large amount of refactoring. We will talk about transforming later.
mouseMove(): Compute particle index from mouse position on screen to polar coordinates, and make sure the disturbance wrap around:
Define the function (outside mouseMove(), we need this again later)
function wrapAround(i, a) { return (i + a.length) % a.length; }
Then change
particles[target - 2] --> particles[wrapAround(target - 2, particles)]
particles[target - 1] --> particles[wrapAround(target - 1, particles)]
...
The modulo operator does the job but I added particles.length so I don't modulo a negative number.
render(): Make sure the force calculation wrap around, so we need to wrapAround function again. We can strip away the two if statements:
fExtensionY = particles[wrapAround(u - 1, particles)].y - particles[u].y - springs[wrapAround(u - 1, springs)].iLengthY;
fForceY += -fK * fExtensionY;
fExtensionY = particles[u].y - particles[wrapAround(u + 1, particles)].y - springs[warpAround(u, springs)].iLengthY;
fForceY += fK * fExtensionY;
Here is the result so far in jsfiddle: Notice the wave propagate from the other side. http://jsfiddle.net/DM68M/
After that's done, the hardest part is rendering them on a circle. To do that, we need coordinate transform functions that treat particle's (x, y) as (angle in the circle, distance from center), and we also need inverse transforms for mouse interaction in mouseMove().
function particleCoordsToScreenCoords(particleX, particleY) {
return [ radiusFactor * particleY * Math.cos(particleX / angleFactor),
radiusFactor * particleY * Math.sin(particleX / angleFactor) ];
}
function screenCoordsToParticleCoords(screenX, screenY) {
// something involving Math.atan2 and Math.sqrt
}
Where the ...Factor variables needed to be determined separately. The angleFactor is two pi over the highest x-position found among particles array
Then, in the coordinates supplied to the context.lineTo, context.arc, use the particleCoordsToScreenCoords to transform the coordinates.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
Did you ever played the "Tank wars" game?
I'm programming this game with JavaScript + Canvas (for a personal challenge), and what I need is an algorithm for generating that random green land every time I start the game, but I'm not too good at maths, so I can't do it myself.
I don't want someone to give me the code, I only want the idea for the algorithm.
Thanks!
(9 segments)
Fiddle demo
(7 segments)
The main generation function look like this:
var numOfSegments = 9; // split horizontal space
var segment = canvas.width / numOfSegments; // calc width of each segment
var points = [], calcedPoints;
var variations = 0.22; // adjust this: lower = less variations
var i;
//produce some random heights across the canvas
for(i=0; i < numOfSegments + 1; i++) {
points.push(segment * i);
points.push(canvas.height / 2.8 + canvas.height * variations * Math.random());
}
//render the landscape
ctx.beginPath();
ctx.moveTo(canvas.width, canvas.height);
ctx.lineTo(0, canvas.height);
calcedPoints = ctx.curve(points); // see below
ctx.closePath();
ctx.fillStyle = 'green';
ctx.fill();
The curve() function is a separate function which generate a cardinal spline. In here you can modify it to also store tension values to make more spikes. You can also used the generated points as a basis for where and at what angle the tanks will move at.
The function for cardinal spline:
CanvasRenderingContext2D.prototype.curve = function(pts, tension, numOfSegments) {
tension = (tension != 'undefined') ? tension : 0.5;
numOfSegments = numOfSegments ? numOfSegments : 16;
var _pts = [], res = [], t, i, l, r = 0,
x, y, t1x, t2x, t1y, t2y,
c1, c2, c3, c4, st, st2, st3, st23, st32;
_pts = pts.concat();
_pts.unshift(pts[1]);
_pts.unshift(pts[0]);
_pts.push(pts[pts.length - 2]);
_pts.push(pts[pts.length - 1]);
l = (_pts.length - 4);
for (i = 2; i < l; i+=2) {
//overrides and modifies tension for each segment.
tension = 1 * Math.random() - 0.3;
for (t = 0; t <= numOfSegments; t++) {
t1x = (_pts[i+2] - _pts[i-2]) * tension;
t2x = (_pts[i+4] - _pts[i]) * tension;
t1y = (_pts[i+3] - _pts[i-1]) * tension;
t2y = (_pts[i+5] - _pts[i+1]) * tension;
st = t / numOfSegments;
st2 = st * st;
st3 = st2 * st;
st23 = st3 * 2;
st32 = st2 * 3;
c1 = st23 - st32 + 1;
c2 = -(st23) + st32;
c3 = st3 - 2 * st2 + st;
c4 = st3 - st2;
x = c1 * _pts[i] + c2 * _pts[i+2] + c3 * t1x + c4 * t2x;
y = c1 * _pts[i+1] + c2 * _pts[i+3] + c3 * t1y + c4 * t2y;
res[r++] = x;
res[r++] = y;
} //for t
} //for i
l = res.length;
for(i=0;i<l;i+=2) this.lineTo(res[i], res[i+1]);
return res; //return calculated points
}
Look into perlin noise generation, this in combination with a good smoothing algorithm can produce some pretty good terrain, and is fairly quick. There is a reference version of the code kicking around the net somewhere, which should provide you with a fairly hefty headstart
First you need a point that is random y (between 55,65); got x=0
So this is the origin point for the green, lets keep it as x1,y1 (x1 always 0).
Then you need a random integer between 30 to 40. This is x2. And a random y which is in the range y1 + 8 to y1 + 20.
Then x3 and y3 on same principle (lets call it formula type 1)
Now you need to first get a random either -1 or 1, this will be directions of y4. So y4 can go higher than y3 or lower ... this will be formula type 2.
You need to keep a max and min y for a new y, if it crosses that then go the other way -> this will be a correction type formula 3.
Xn keeps increasing till its >= width of board.
Join the lines in a eclipses ... and looks like web searches is the way to go !
I am sure there are a lot of coded libraries that you could use to make this easy. But if you are trying to code this by yourself, here is my idea.
You need to define terrain from everything else. So every part of your environment is a cluster for example. You need to define how are separated these clusters, by nodes(points) for example.
You can create a polygon from a sequence of points, and this polygon can become whatever you want, in this case terrain.
See that on the image you passed, there are peaks, those are the nodes (points). Remember to define also nodes on the borders of your environment.
There are surely a novel, written algorithms, either fractal as #DesertIvy pointed out or others, maybe there are libraries as well, but if you want toi generate what is in the image, it can be pretty straightforward, since it is just (slightly curved) lines between points. If you do it in phases, not trying to be correct at once, it is easy:
Split x region of your game screen into sections (with some minimal and maximal width) using random (you may be slightly off in last section, but it does not matter as much, I think). Remember the x-es where sections meet (including the ones at game screen border)
Prepare some data structure to include y-s as well, on previously remembered x-s. Start with leftmost.y = 0, slope = Math.random()-0.5;.
Generate each next undefined y beginning with 1: right.y = left.y + slope * (right.x-left.x); as well as update slope after each y: slope += Math.random()-0.5;. Do not bother, for the moment, if it all fits into game screen.
If you want arcs, you can generate "curviness" parameter for each section randomly which represent how much the middle of the line is bumped compared to straight lines.
Fit the ys into the game screen: first find maximal and minimal generated y (mingeny, maxgeny) (you can track this while generating in point 4). Choose where the max and min y in game screen (minscry, maxscry) (say at the top fourth and at the bottom fourth). Then transform generated ys so that it spans between minscry and maxscry: for every point, do apoint.y = minscry + (maxscry-minscry)/(maxgeny-mingeny)*(apoint.y-mingeny).
Now use lines between [x,y] points as a terrain, if you want to use "curviness", than add curvemodifier to y for any particular x in a section between leftx and rightx. The arc need not to be a circle: I would suggest a parabola or cosine which are easy to produce: var middle = (left.x+right.x)/2; var excess = (x-left)/(middle-left); and then either var curvemodifier = curviness * (1-excess*excess); or var curvemodifier = curviness * Math.cos(Math.PI/2*excess).
Wow...At one point I was totally addicted to tank wars.
Since you are on a learning adventure...
You might also learn about the context.globalCompositeOperation.
This canvas operation will let you grab an image of actual grass and composite it into your game.
You can randomize the grass appearance by changing the x/y of your drawImage();
Yes, the actual grass would probably be too distracting to include in your finished game, but learning about compositing would be valuable knowledge to have.
...and +1 for the question: Good for you in challenging yourself !
I am creating a new "whack-a-mole" style game where the children have to hit the correct numbers in accordance to the question. So far it is going really well, I have a timer, count the right and wrong answers and when the game is started I have a number of divs called "characters" that appear in the container randomly at set times.
The problem I am having is that because it is completely random, sometimes the "characters" appear overlapped with one another. Is there a way to organize them so that they appear in set places in the container and don't overlap when they appear.
Here I have the code that maps the divs to the container..
function randomFromTo(from, to) {
return Math.floor(Math.random() * (to - from + 1) + from);
}
function scramble() {
var children = $('#container').children();
var randomId = randomFromTo(1, children.length);
moveRandom('char' + randomId);
}
function moveRandom(id) {
var cPos = $('#container').offset();
var cHeight = $('#container').height();
var cWidth = $('#container').width();
var pad = parseInt($('#container').css('padding-top').replace('px', ''));
var bHeight = $('#' + id).height();
var bWidth = $('#' + id).width();
maxY = cPos.top + cHeight - bHeight - pad;
maxX = cPos.left + cWidth - bWidth - pad;
minY = cPos.top + pad;
minX = cPos.left + pad;
newY = randomFromTo(minY, maxY);
newX = randomFromTo(minX, maxX);
$('#' + id).css({
top: newY,
left: newX
}).fadeIn(100, function () {
setTimeout(function () {
$('#' + id).fadeOut(100);
window.cont++;
}, 1000);
});
I have a fiddle if it helps.. http://jsfiddle.net/pUwKb/8/
As #aug suggests, you should know where you cannot place things at draw-time, and only place them at valid positions. The easiest way to do this is to keep currently-occupied positions handy to check them against proposed locations.
I suggest something like
// locations of current divs; elements like {x: 10, y: 40}
var boxes = [];
// p point; b box top-left corner; w and h width and height
function inside(p, w, h, b) {
return (p.x >= b.x) && (p.y >= b.y) && (p.x < b.x + w) && (p.y < b.y + h);
}
// a and b box top-left corners; w and h width and height; m is margin
function overlaps(a, b, w, h, m) {
var corners = [a, {x:a.x+w, y:a.y}, {x:a.x, y:a.y+h}, {x:a.x+w, y:a.y+h}];
var bWithMargins = {x:b.x-m, y:b.y-m};
for (var i=0; i<corners.length; i++) {
if (inside(corners[i], bWithMargins, w+2*m, h+2*m) return true;
}
return false;
}
// when placing a new piece
var box;
while (box === undefined) {
box = createRandomPosition(); // returns something like {x: 15, y: 92}
for (var i=0; i<boxes.length; i++) {
if (overlaps(box, boxes[i], boxwidth, boxheight, margin)) {
box = undefined;
break;
}
}
}
boxes.push(box);
Warning: untested code, beware the typos.
The basic idea you will have to implement is that when a random coordinate is chosen, theoretically you SHOULD know the boundaries of what is not permissible and your program should know not to choose those places (whether you find an algorithm or way of simply disregarding those ranges or your program constantly checks to make sure that the number chosen isn't within the boundary is up to you. the latter is easier to implement but is a bad way of going about it simply because you are entirely relying on chance).
Let's say for example coordinate 50, 70 is selected. If the picture is 50x50 in size, the range of what is allowed would exclude not only the dimensions of the picture, but also 50px in all directions of the picture so that no overlap may occur.
Hope this helps. If I have time, I might try to code an example but I hope this answers the conceptual aspect of the question if that is what you were having trouble with.
Oh and btw forgot to say really great job on this program. It looks awesome :)
You can approach this problem in at least two ways (these two are popped up in my head).
How about to create a 2 dimensional grid segmentation based on the number of questions, the sizes of the question panel and an array holding the position of each question coordinates and then on each time frame to position randomly these panels on one of the allowed coordinates.
Note: read this article for further information: http://eloquentjavascript.net/chapter8.html
The second approach follow the same principle, but this time to check if the panel overlap the existing panel before you place it on the canvas.
var _grids;
var GRID_SIZE = 20 //a constant holding the panel size;
function createGrids() {
_grids = new Array();
for (var i = 0; i< stage.stageWidth / GRID_SIZE; i++) {
_grids[i] = new Array();
for (var j = 0; j< stage.stageHeight / GRID_SIZE; j++) {
_grids[i][j] = new Array();
}
}
}
Then on a separate function to create the collision check. I've created a gist for collision check in Actionscript, but you can use the same principle in Javascript too. I've created this gist for inspirational purposes.
Just use a random number which is based on the width of your board and then modulo with the height...
You get a cell which is where you can put the mole.
For the positions the x and y should never change as you have 9 spots lets say where the mole could pop up.
x x x
x x x
x x x
Each cell would be sized based on % rather then pixels and would allow re sizing the screen
1%3 = 1 (x)
3%3 = 0 (y)
Then no overlap is possible.
Once the mole is positioned it can be show or hidden or moved etc based on some extended logic if required.
If want to keep things your way and you just need a quick re-position algorithm... just set the NE to the SW if the X + width >= x of the character you want to check by setting the x = y+height of the item which overlaps. You could also enforce that logic in the drawing routine by caching the last x and ensuring the random number was not < last + width of the item.
newY = randomFromTo(minY, maxY);
newX = randomFromTo(minX, maxX); if(newX > lastX + characterWidth){ /*needful*/}
There could still however be overlap...
If you wanted to totally eliminate it you would need to keep track of state such as where each x was and then iterate that list to find a new position or position them first and then all them to move about randomly without intersecting which would would be able to control with just padding from that point.
Overall I think it would be easier to just keep X starting at 0 and then and then increment until you are at a X + character width > greater then the width of the board. Then just increase Y by character height and Set X = 0 or character width or some other offset.
newX = 0; newX += characterWidth; if(newX + chracterWidth > boardWidth) newX=0; newY+= characterHeight;
That results in no overlap and having nothing to iterate or keep track of additional to what you do now, the only downside is the pattern of the displayed characters being 'checker board style' or right next to each other (with possible random spacing in between horizontal and vertical placement e.g. you could adjust the padding randomly if you wanted too)
It's the whole random thing in the first place that adds the complexity.
AND I updated your fiddle to prove I eliminated the random and stopped the overlap :)
http://jsfiddle.net/pUwKb/51/
How can I place rectangles with variable width and height, randomly in a stage but away from a circle in the center which has radius of x
Thanks in advance
EDIT
check my code so far
http://jsfiddle.net/chchrist/cAShH/1/
The three potential options I would follow are:
Generate random coordinates in [400,400] and then check that the distance from [200,200] is less than 50. If it is, fine; if not, start again.
Generate random polar coordinates (i.e., angle and distance), where the distance is greater than 50. Then convert these to Cartesian, centred around [200,200] and bounded to your area... The problem with this approach is that it would introduce bias at the extremities of your rectangular area.
Ignore the circle and bound it by a square, then use the first approach but with simplified logic.
One approach might be to think about how to map uniform random numbers into legal positions.
For example (simplifying slightly), if you had a 200 x 200 square, and you wanted to avoid any points in a 100x100 square in the middle, you could do the following for each coordinate. Generate a random number between 0 and 100. If it's less than 50, use it directly; otherwise add 100 to it (to put it in the 150-200 range)
Conceptually this stretches the range around the "hole" in the middle, while still leaving the resulting points uniformly distributed.
It'll be trickier with your circle, as the axes are not independent, but a variation on this method could be worth considering. (Especially if you only have "soft" requirements for randomness and so can relax the constraints on the distribution somewhat).
I would start with a coordinate system centered at 0,0 and after you have generated valid coordinates map them onto your square/rectangle.
Here's a simple example:
function getValidCoordinates() {
var x, y, isValid = false;
while (!isValid) {
x = Math.random() * 400 - 200;
y = Math.random() * 400 - 200;
if (Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) > 50)
isValid = true;
//else alert('too close ' + x + ',' + y);
}
return {x: x + 200, y: y + 200};
}
for (var i=0; i < 10; i++) {
var co = getValidCoordinates();
alert('x=' + co.x + ', y=' + co.y);
}