Libgdx: Animating line drawing - libgdx

I want to draw a big V on the game screen (0,0) to (45,45) to (90,0).
But I also want it to animate when the line is drawn.
Below is the pseudo code. But I guess there is a better way to achieve this because I need to draw about 50 V with different sizes.
int x = 0;
int y = 0;
//drawing method
if( x <= 45 && y <= 45 ){
x++;
y++;
draw line from 0,0 to x,y
}else if( x <= 90 && y >= 0 ){
x++;
y- -;
draw another line from 45,45 to x,y
}

Related

How do I constrain an angle from rotating in AS3?

I have a gun and a player. I want to constrain the angle of the gun so the player doesn't raise his gun up too much or too low. The player and gun turns to the right side when the mouse is facing the right, and if the mouse faces the left, the player and gun turns to the left. I want to constrain the gun between 160 and -160 when it faces right. And constrain the gun between 20 and -20 when it faces left. So it doesn't rotate over the constraining restriction.
I have a code that makes it rotate 360, but I'm not sure on how to stop it from rotating once it reaches a certain point.
if (parent != null)
{
var dx = MovieClip(parent).crosshair.x - x;
var dy = MovieClip(parent).crosshair.y - y;
var angle = Math.atan2(dy, dx)/Math.PI * 180;
rotation = angle;
}
Ok, here's what's happening:
Flash rotation at 0° faces strictly up. So the right side will be from 0° to 180° and left side will be from 0° to -180°. This is easy to separate because all right side > 0 and all left side < 0.
But, Math.atan2(dy, dx) calculates a different angle which cannot be directly assigned to object rotation. Instead of left and right side, it is < 0 on upper side and > 0 on lower side. If you calculate the rotation that way, it will be a mess.
So, the atan calculation must be shifted by 90° clockwise in order to match the Flash rotation. This is done by transforming the parameters and now it looks like Math.atan2(dx, -dy). After that the calculated angle and the rotation angle will match.
var angle:Number = Math.atan2(dx, -dy) / Math.PI * 180;
if (angle < 0) { // facing left
if (angle > -30) angle = -30;
if (angle < -150) angle = -150;
} else { // facing right
if (angle < 30) angle = 30;
if (angle > 150) angle = 150;
}
This is the solution without using -dy and instead using dy. (Code added by OP and I didn't check it :)
var angle = Math.atan2(dy, dx) / Math.PI * 180;
if (rotation > -180 && rotation < -90 || rotation > 90 && rotation < 180 )
{ // facing left
if (rotation > -150 && rotation < 0)
{
rotation = -150;
}
if (rotation < 120 && rotation > 0)
{
rotation = 120;
}
}
else
{
{ // facing right
if (rotation < -30)
{
rotation = -30;
}
if (rotation > 60)
{
rotation = 60;
}
}

simple snake game - libgdx

I'm trying to develop a simple snake game with libgdx. My problem is that everytime I want to spawn some apples(texture, 20px width X 20px height) it always overlaps the body of the snake.
I'm trying to avoid this but it keeps occuring during the game.
The snake is compiled of parts - every part is a texture of 20px width X 20px height(The screen width is 480px width X 800px height)
Here is what I have tried so far:
public void addApple() {
accomplishedSnake = false;
accomplishedApples = false;
while (!accomplishedSnake && !accomplishedApples) {
xApple = 20 * MathUtils.random(0, 23);
yApple = 20 * MathUtils.random(20, 36);
if (!accomplishedSnake) {
for (int i = 0; i < snake.getSize(); i++) {
if (snake.getPart(i).getX() <= xApple
&& snake.getPart(i).getX() + 20 >= xApple
&& yApple >= snake.getPart(i).getY()
&& yApple <= snake.getPart(i).getY() + 20)
break;
if (i == snake.getSize() - 1) {
accomplishedSnake = true;
break;
}
}
}
if (!accomplishedApples) {
for (int i = 0; i < apples.size; i++) {
if (apples.get(i).getX() <= xApple && apples.get(i).getX()+20 >= xApple
&& yApple >= apples.get(i).getY() && yApple <= apples.get(i).getY()+20)
break;
if (i == apples.size - 1) {
accomplishedApples = true;
break;
}
}
}
}
apples.add(new Apple(xApple, yApple));
}
The code is pretty self-explanatory. In every moment I have 3 different apples on the screen. This code tries to raffle x-y coordinates to the new apple but before the apple is added to the screen and rendered, I want to make sure that it doesn't overlaps the body of the snake or the other apples.
I just can't see what's wrong with this code.
P.S I tried to use the overlaps method in the Rectangle class but it doesn't work.
You test conditions are too simple. Each item snake body part/apple has size, you need to consider their locus. So [snake.X,snake.X+20] and [snake.Y,snake.Y+20] is occupied by each body part, you need to ensure both apple.X and apple.X+20 aren't in range, the same for apple.Y
try this ..
if (snake.getPart(i).getX() >= xApple
&& snake.getPart(i).getX() + 20 <= xApple
&& snake.getPart(i).getX() >= xApple+20
&& snake.getPart(i).getX() + 20 <= xApple+20
&& snake.getPart(i).getY() >= yApple
&& snake.getPart(i).getY() + 20 <= yApple
&& snake.getPart(i).getY() >= yApple +20
&& snake.getPart(i).getY() + 20 <= yApple +20)
break;
also you need to ensure accomplishedApple and accomplishedSnake are set to false both before entering the while loop and after each calculation of random coordinates.
you also need to mimic this logic when establishing accomplishedApple further down your code.
This game should be tile-based.
This means, that the game is organized as a grid, where every cell has the same size.
This is done by using a camera:
OrthographicCamera cam = new OrthographicCamera(viewportWidth, viewportHeight)
The viewportWidth and viewportHeight define how many cells there should be in x and y.
As you are using a resolution of 480*800px and pictures with a size of 20*20px, the viewportWidth should be 480/20=24 and the viewportHeight should be 800/20 = 40.
Note, that the cameras P(0/0) is in the middle of the screen and you see objects from -12 to 12 (x) and -20 to 20 (y). Just set the position of the camera to P(12/20) and the P(0/0) is the lower left corner, as usual.
Now the spawning would be easy:
I use a int[][] world, where i store, if there is a:
Snakepart at P(x,y) (world[x][y] == 1)
Apple at P(x,y) (world[x][y] == 2)
Nothing at P(x,y) (world[x][y] == 0)
This means, that if the snake leaves a tile, you need to set its value to 0 (world[x][y] = 0) and every tile it enters to 1 (world[x][y] = 1)
public void spawnApple() {
boolean spawned = false;
while(!spawned) {
// The lower left corner is always an int-value
int x = (int)MathUtils.random(0, 23);
int y = (int)MathUtils.random(0, 40);
if (world[x][y] == 0) {
// Add Apple at x,y
world[x][y] = 2;
}
}
}
Hope it helps!
private void checkAndPlaceApple() {
if(!appleAvailable) {
do {
appleX = MathUtils.random(Gdx.graphics.getWidth / 20 - 1) * 20;
appleY = MathUtils.random(Gdx.graphics.getHeight / 20 - 1) * 20;
appleAvailable = true;
} while(appleX == snakeX && appleY == snakeY);
}
}
The previous code shows the required rule for placing the apple on the
screen. First, we check whether we need to place an apple, then we randomly pick
a location on the screen, which is a multiple of 20, and we repick it if the picked location contains the snake. As we are working in a 0-indexed environment we need to subtract one (1-20 becomes 0-19 and 1-15 becomes 0-14).

Tank with Rotating Turret AS3

I'm making a battleship simulator that controls a battleship with the WASD keys and the turret with the mouse pointer. The turret can move 360 degrees.
It rotates as it should; however, whenever the mouse pointer makes the turret reach an angle of 0 or 360 degrees, it begins rotating endlessly until I move the mouse pointer back to a different angle.
Attached is the code I have so far for turret movement:
var PTurret1angle:Number = 270;
function PTurretRotate(Evt:Event){
var Turret1x:Number;
var Turret1y:Number;
var Turret1Angle:Number;
Turret1x = mvi_PTurret1.x - mouseX;
Turret1y = mvi_PTurret1.y - mouseY;
Turret1Angle = Math.round(Math.atan2(Turret1y,Turret1x) * (180/Math.PI) + 180);
if(Turret1Angle > PTurret1angle){
mvi_PTurret1.rotation += 1;
PTurret1angle += 1;
if(PTurret1angle == 360){
PTurret1angle = 0;
}
}
else if(Turret1Angle < PTurret1angle){
mvi_PTurret1.rotation -= 1;
PTurret1angle -= 1;
if(PTurret1angle == 0){
PTurret1angle = 360;
}
}
txt_Turret1Angle.text = Turret1Angle.toString();
txt_PTurret.text = PTurret1angle.toString();
}
So, my two questions are:
1) How do I ensure that the turret will remain locked on to where the mouse pointer is, regardless of mouse pointer position?
2) Is there any way to make the rotation more efficient? For example, if my pointer requires the turret to only turn about 30 degrees, it will actually turn 330 degrees depending on the circumstance.
Thank you for your help.
Your turret angles are funky because of these two if statements:
if(PTurret1angle == 0){
PTurret1angle = 360;
}
and
if(PTurret1angle == 360){
PTurret1angle = 0;
}
These are making your endless rotation (mouse on top, angle is zero, angle is set to 360 which is greater than zero, you subtract one, oh man now it's at 359 which is greater than zero, gotta rotate all the way around, oh man we got to zero, gotta set it to 360, ......etc.....).
You can accomplish the "efficient rotation" by checking the difference between Turret1Angle and PTurret1angle. Here are my assumptions:
Zero is pointing straight up.
Positive rotation is clockwise rotation.
Turret1Angle is mouse angle and PTurret1angle is actual current turret angle
The most you ever want to turn is 180 degrees. (efficient rotation)
That being said, you can figure out which way to turn based on two things: the sign of the difference between Turret1Angle (mouse angle) and PTurret1angle (actual turret angle), and the magnitude of this difference. What do I mean by this?
examples using Turret1Angle (mouse) - PTurret1angle (actual):
Mouse is at 1 degree, turret is at 359. Mouse - turret = -358. The most you want to turn is 180 degrees, so since abs(-358) > 180, then add 360 (as the difference is negative). This gives you +2, which means turn 2 degrees clockwise!
Mouse is at 359, turret is at 1. Mouse - turret = 358. abs(358) > 180, so subtract 360 degrees (as the difference is positive). This gives you -2, so turn 2 degrees counterclockwise!
Mouse is at 1, turret is at 3. Mouse - turret = -2. Since abs(-2) < 180, we don't need to add 360, just turn 2 degrees counterclockwise!
I'm a little rusty with my ActionScript, so I won't actually code this out for you. I think I've explained how to implement the two fixes you asked about thoroughly, but if you have any trouble I'd be happy to psuedocode it.
EDIT: Here's some psuedocode:
var AngleDiff:Number;
// starting after declarations/getting basic information, within your function
Turret1Angle = Math.round(Math.atan2(Turret1y,Turret1x) * (180/Math.PI) + 180);
AngleDiff = Turret1Angle - PTurret1angle;
if(Math.abs(AngleDiff) > 180){ // efficient movement
if(AngleDiff > 0){
AngleDiff -= 360;
}else if(AngleDiff < 0){
AngleDiff += 360;
}
if(AngleDiff > 0){ // do the actual movement
PTurret1Angle += 1;
mvi_PTurret1.rotation += 1;
}else if(AngleDiff < 0){
PTurret1Angle -= 1;
mvi_PTurret1.rotation -= 1;
}
You can probably fix the numbers greater than 360 problem with modulo division, as Lukasz suggests.
PTurret1Angle = PTurret1Angle % 360;
(note: that was more actual code than psuedocode. I haven't actually tested it though so it may/may not work)

Canvas 3d graph

I have done a 3d graph to plot points in it. I have drawn x,y and z axis. Also you can rotate the axis by pressing arrow keys.Now my problem marking the axis as x,y and z .I tried to add text in canvas by using filltext.But the text gets added to canvas but its not rotating.It is because i have not set rotation effect for it i guess.So how can i set the rotation to text so that when axis rotates the text also rotates together.Below is my code.
<!DOCTYPE html>
<html>
<head>
<title>Canvas Surface Rotation</title>
<style>
body {
text-align: center;
}
canvas {
border: 1px solid black;
}
</style>
<script>
var constants = {
canvasWidth: 600, // In pixels.
canvasHeight: 600, // In pixels.
leftArrow: 37,
upArrow: 38,
rightArrow: 39,
downArrow: 40,
xMin: -10, // These four max/min values define a square on the xy-plane that the surface will be plotted over.
xMax: 10,
yMin: -10,
yMax: 10,
xDelta: 0.01, // Make smaller for more surface points.
yDelta: 0.01, // Make smaller for more surface points.
colorMap: ["#060"], // There are eleven possible "vertical" color values for the surface, based on the last row of http://www.cs.siena.edu/~lederman/truck/AdvanceDesignTrucks/html_color_chart.gif
pointWidth: 2, // The size of a rendered surface point (i.e., rectangle width and height) in pixels.
dTheta: 0.05, // The angle delta, in radians, by which to rotate the surface per key press.
surfaceScale: 24 // An empirically derived constant that makes the surface a good size for the given canvas size.
};
// These are constants too but I've removed them from the above constants literal to ease typing and improve clarity.
var X = 0;
var Y = 1;
var Z = 2;
// -----------------------------------------------------------------------------------------------------
var controlKeyPressed = false; // Shared between processKeyDown() and processKeyUp().
var surface = new Surface(); // A set of points (in vector format) representing the surface.
// -----------------------------------------------------------------------------------------------------
function point(x, y, z)
/*
Given a (x, y, z) surface point, returns the 3 x 1 vector form of the point.
*/
{
return [x, y, z]; // Return a 3 x 1 vector representing a traditional (x, y, z) surface point. This vector form eases matrix multiplication.
}
// -----------------------------------------------------------------------------------------------------
function Surface()
/*
A surface is a list of (x, y, z) points, in 3 x 1 vector format. This is a constructor function.
*/
{
this.points = []; // An array of surface points in vector format. That is, each element of this array is a 3 x 1 array, as in [ [x1, y1, z1], [x2, y2, z2], [x3, y3, z3], ... ]
}
// -----------------------------------------------------------------------------------------------------
Surface.prototype.equation = function(x, y)
/*
Given the point (x, y), returns the associated z-coordinate based on the provided surface equation, of the form z = f(x, y).
*/
{
var d = Math.sqrt(x*x + y*y); // The distance d of the xy-point from the z-axis.
return 4*(Math.sin(d) / d); // Return the z-coordinate for the point (x, y, z).
}
// -----------------------------------------------------------------------------------------------------
Surface.prototype.generate = function()
/*
Creates a list of (x, y, z) points (in 3 x 1 vector format) representing the surface.
*/
{
var i = 0;
for (var x = constants.xMin; x <= constants.xMax; x += constants.xDelta)
{
for (var y = constants.yMin; y <= constants.yMax; y += constants.yDelta)
{
this.points[i] = point(x, y, this.equation(x, y)); // Store a surface point (in vector format) into the list of surface points.
++i;
}
}
}
// -----------------------------------------------------------------------------------------------------
Surface.prototype.color = function()
/*
The color of a surface point is a function of its z-coordinate height.
*/
{
var z; // The z-coordinate for a given surface point (x, y, z).
this.zMin = this.zMax = this.points[0][Z]; // A starting value. Note that zMin and zMax are custom properties that could possibly be useful if this code is extended later.
for (var i = 0; i < this.points.length; i++)
{
z = this.points[i][Z];
if (z < this.zMin) { this.zMin = z; }
if (z > this.zMax) { this.zMax = z; }
}
var zDelta = Math.abs(this.zMax - this.zMin) / constants.colorMap.length;
for (var i = 0; i < this.points.length; i++)
{
this.points[i].color = constants.colorMap[ Math.floor( (this.points[i][Z]-this.zMin)/zDelta ) ];
}
/* Note that the prior FOR loop is functionally equivalent to the follow (much less elegant) loop:
for (var i = 0; i < this.points.length; i++)
{
if (this.points[i][Z] <= this.zMin + zDelta) {this.points[i].color = "#060";}
else if (this.points[i][Z] <= this.zMin + 2*zDelta) {this.points[i].color = "#090";}
else if (this.points[i][Z] <= this.zMin + 3*zDelta) {this.points[i].color = "#0C0";}
else if (this.points[i][Z] <= this.zMin + 4*zDelta) {this.points[i].color = "#0F0";}
else if (this.points[i][Z] <= this.zMin + 5*zDelta) {this.points[i].color = "#9F0";}
else if (this.points[i][Z] <= this.zMin + 6*zDelta) {this.points[i].color = "#9C0";}
else if (this.points[i][Z] <= this.zMin + 7*zDelta) {this.points[i].color = "#990";}
else if (this.points[i][Z] <= this.zMin + 8*zDelta) {this.points[i].color = "#960";}
else if (this.points[i][Z] <= this.zMin + 9*zDelta) {this.points[i].color = "#930";}
else if (this.points[i][Z] <= this.zMin + 10*zDelta) {this.points[i].color = "#900";}
else {this.points[i].color = "#C00";}
}
*/
}
// -----------------------------------------------------------------------------------------------------
function appendCanvasElement()
/*
Creates and then appends the "myCanvas" canvas element to the DOM.
*/
{
var canvasElement = document.createElement('canvas');
canvasElement.width = constants.canvasWidth;
canvasElement.height = constants.canvasHeight;
canvasElement.id = "myCanvas";
canvasElement.getContext('2d').translate(constants.canvasWidth/2, constants.canvasHeight/2); // Translate the surface's origin to the center of the canvas.
document.body.appendChild(canvasElement); // Make the canvas element a child of the body element.
}
//------------------------------------------------------------------------------------------------------
Surface.prototype.sortByZIndex = function(A, B)
{
return A[Z] - B[Z]; // Determines if point A is behind, in front of, or at the same level as point B (with respect to the z-axis).
}
// -----------------------------------------------------------------------------------------------------
Surface.prototype.draw = function()
{
var myCanvas = document.getElementById("myCanvas"); // Required for Firefox.
var ctx = myCanvas.getContext("2d");
this.points = surface.points.sort(surface.sortByZIndex); // Sort the set of points based on relative z-axis position. If the points are visibly small, you can sort of get away with removing this step.
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.font="20px Arial";
ctx.fillText("X",250,0);
for (var i = 0; i < this.points.length; i++)
{
ctx.fillStyle = this.points[i].color;
ctx.fillRect(this.points[i][X] * constants.surfaceScale, this.points[i][Y] * constants.surfaceScale, constants.pointWidth, constants.pointWidth);
}
}
// -----------------------------------------------------------------------------------------------------
Surface.prototype.multi = function(R)
/*
Assumes that R is a 3 x 3 matrix and that this.points (i.e., P) is a 3 x n matrix. This method performs P = R * P.
*/
{
var Px = 0, Py = 0, Pz = 0; // Variables to hold temporary results.
var P = this.points; // P is a pointer to the set of surface points (i.e., the set of 3 x 1 vectors).
var sum; // The sum for each row/column matrix product.
for (var V = 0; V < P.length; V++) // For all 3 x 1 vectors in the point list.
{
Px = P[V][X], Py = P[V][Y], Pz = P[V][Z];
for (var Rrow = 0; Rrow < 3; Rrow++) // For each row in the R matrix.
{
sum = (R[Rrow][X] * Px) + (R[Rrow][Y] * Py) + (R[Rrow][Z] * Pz);
P[V][Rrow] = sum;
}
}
}
// -----------------------------------------------------------------------------------------------------
Surface.prototype.erase = function()
{
var myCanvas = document.getElementById("myCanvas"); // Required for Firefox.
var ctx = myCanvas.getContext("2d");
ctx.clearRect(-constants.canvasWidth/2, -constants.canvasHeight/2, myCanvas.width, myCanvas.height);
}
// -----------------------------------------------------------------------------------------------------
Surface.prototype.xRotate = function(sign)
/*
Assumes "sign" is either 1 or -1, which is used to rotate the surface "clockwise" or "counterclockwise".
*/
{
var Rx = [ [0, 0, 0],
[0, 0, 0],
[0, 0, 0] ]; // Create an initialized 3 x 3 rotation matrix.
Rx[0][0] = 1;
Rx[0][1] = 0; // Redundant but helps with clarity.
Rx[0][2] = 0;
Rx[1][0] = 0;
Rx[1][1] = Math.cos( sign*constants.dTheta );
Rx[1][2] = -Math.sin( sign*constants.dTheta );
Rx[2][0] = 0;
Rx[2][1] = Math.sin( sign*constants.dTheta );
Rx[2][2] = Math.cos( sign*constants.dTheta );
this.multi(Rx); // If P is the set of surface points, then this method performs the matrix multiplcation: Rx * P
this.erase(); // Note that one could use two canvases to speed things up, which also eliminates the need to erase.
this.draw();
}
// -----------------------------------------------------------------------------------------------------
Surface.prototype.yRotate = function(sign)
/*
Assumes "sign" is either 1 or -1, which is used to rotate the surface "clockwise" or "counterclockwise".
*/
{
var Ry = [ [0, 0, 0],
[0, 0, 0],
[0, 0, 0] ]; // Create an initialized 3 x 3 rotation matrix.
Ry[0][0] = Math.cos( sign*constants.dTheta );
Ry[0][1] = 0; // Redundant but helps with clarity.
Ry[0][2] = Math.sin( sign*constants.dTheta );
Ry[1][0] = 0;
Ry[1][1] = 1;
Ry[1][2] = 0;
Ry[2][0] = -Math.sin( sign*constants.dTheta );
Ry[2][1] = 0;
Ry[2][2] = Math.cos( sign*constants.dTheta );
this.multi(Ry); // If P is the set of surface points, then this method performs the matrix multiplcation: Rx * P
this.erase(); // Note that one could use two canvases to speed things up, which also eliminates the need to erase.
this.draw();
}
// -----------------------------------------------------------------------------------------------------
Surface.prototype.zRotate = function(sign)
/*
Assumes "sign" is either 1 or -1, which is used to rotate the surface "clockwise" or "counterclockwise".
*/
{
var Rz = [ [0, 0, 0],
[0, 0, 0],
[0, 0, 0] ]; // Create an initialized 3 x 3 rotation matrix.
Rz[0][0] = Math.cos( sign*constants.dTheta );
Rz[0][1] = -Math.sin( sign*constants.dTheta );
Rz[0][2] = 0; // Redundant but helps with clarity.
Rz[1][0] = Math.sin( sign*constants.dTheta );
Rz[1][1] = Math.cos( sign*constants.dTheta );
Rz[1][2] = 0;
Rz[2][0] = 0
Rz[2][1] = 0;
Rz[2][2] = 1;
this.multi(Rz); // If P is the set of surface points, then this method performs the matrix multiplcation: Rx * P
this.erase(); // Note that one could use two canvases to speed things up, which also eliminates the need to erase.
this.draw();
}
// -----------------------------------------------------------------------------------------------------
function processKeyDown(evt)
{
if (evt.ctrlKey)
{
switch (evt.keyCode)
{
case constants.upArrow:
// No operation other than preventing the default behavior of the arrow key.
evt.preventDefault(); // This prevents the default behavior of the arrow keys, which is to scroll the browser window when scroll bars are present. The user can still scroll the window with the mouse.
break;
case constants.downArrow:
// No operation other than preventing the default behavior of the arrow key.
evt.preventDefault();
break;
case constants.leftArrow:
// console.log("ctrl+leftArrow");
surface.zRotate(-1); // The sign determines if the surface rotates "clockwise" or "counterclockwise".
evt.preventDefault();
break;
case constants.rightArrow:
// console.log("ctrl+rightArrow");
surface.zRotate(1);
evt.preventDefault();
break;
}
return; // When the control key is pressed, only the left and right arrows have meaning, no need to process any other key strokes (i.e., bail now).
}
// Assert: The control key is not pressed.
switch (evt.keyCode)
{
case constants.upArrow:
// console.log("upArrow");
surface.xRotate(1);
evt.preventDefault();
break;
case constants.downArrow:
// console.log("downArrow");
surface.xRotate(-1);
evt.preventDefault();
break;
case constants.leftArrow:
// console.log("leftArrow");
surface.yRotate(-1);
evt.preventDefault();
break;
case constants.rightArrow:
// console.log("rightArrow");
surface.yRotate(1);
evt.preventDefault();
break;
}
}
// -----------------------------------------------------------------------------------------------------
Surface.prototype.plot = function(x, y, z)
/*
add the point (x, y, z) (in 3 x 1 vector format) to the surface.
*/
{
this.points.push(point(x, y, z)); // Store a surface point
var x=0;
for (var x = constants.xMin; x <= constants.xMax; x += constants.xDelta)
{
this.points.push(point(x, 0, 0));
}
/*for (var x = constants.xMax+1; x <= constants.xMax+2; x += constants.xDelta)
{
this.points.push(point(11, 0, 0))
}*/
for (var x = constants.xMin; x <= constants.xMax; x += constants.yDelta)
{
this.points.push(point(0, x, 0));
}
for (var x = constants.xMin; x <= constants.xMax; x += constants.yDelta)
{
this.points.push(point(0,0,x));
}
}
function onloadInit()
{
appendCanvasElement(); // Create and append the canvas element to the DOM.
surface.draw(); // Draw the surface on the canvas.
document.addEventListener('keydown', processKeyDown, false); // Used to detect if the control key has been pressed.
}
// -----------------------------------------------------------------------------------------------------
//surface.generate(); // Creates the set of points reprsenting the surface. Must be called before color().
surface.plot(1,1,1);
surface.color(); // Based on the min and max z-coordinate values, chooses colors for each point based on the point's z-ccordinate value (i.e., height).
window.addEventListener('load', onloadInit, false); // Perform processing that must occur after the page has fully loaded.
</script>
</head>
<body>
<p>The z-axis extends out from the center of the screen.<br>
To rotate about the x-axis, press the up/down arrow keys.
To rotate about the y-axis, press the left/right arrow keys.
To rotate about the z-axis, press the ctrl+left/ctrl+down arrow keys.
Note that pressing an arrow key down continuously will not rotate the surface. The surface is rotated once per key press.</p>
<!-- The canvas element is append to the DOM here. -->
</body>
</html>
Text is drawn on a rectangular plane. Let the co-ordinates of top left be (xtl,ytl,ztl)
to right corner be (xtr,ytr,ztr) and bottom left be (xbl,ybl,zbl) then any transformations have to be applied to these coordinates and then the coordoinates for the 2D projection onto the canvas have to be calculated. This will produce a parallelogram into which the text can be drawn but would also need to be transformed.
The simplest would be to calculate the top left corner transformation and draw standard text at that point, perhaps reducing text size depending on z.

a color change in transparency

I have an image generated in the javascript HTML5 canvas.
I would now like to say that all the px of a certain color (red for example) have all become transparent
var imgd = context.getImageData(0,0, canvas.widht, canvas.height);
var pix = imgd.data;
// Loop over each pixel and set alpha channel to 255 for every red pixel
for (var i = 0; n = pix.length, i < n; i += 4) {
if ( pix[i ] > 240 && pix[i+1 ] < 15 && pix[i+2] < 15 ) // it is kind of red
pix[i+3] = 255; // alpha channel
}
// Draw the ImageData object at the given (x,y) coordinates.
context.putImageData(imgd, 0,0);
I did not test the code but it should work (you have the global idea if it does not)