Wrong angle while drawing a partial circle with AS3 - actionscript-3

For a flash game project I am working on I want to create a camera which should be able to detect a player through ray-casting. The camera should be able to have different view angles (eg. 45 degrees or 90 degrees), and according to these view angles the ray-casting should vary. Creating the actual view angles using ray-casting doesn't cause a problem, however, for some reason that is beyond me the angles in which these view angles are positioned are wrong.
This is the code I use:
for (var i:Number = 0; i < this._viewAngle; i++)
{
var pointX:Number = (this._viewRange) * Math.cos(this._viewAngle + (i * Math.PI / 180));
var pointY:Number = (this._viewRange) * Math.sin(this._viewAngle + (i * Math.PI / 180));
this._rayHolder.graphics.lineTo(pointX, pointY);
this._rayHolder.graphics.moveTo(0, 0);
}
And this is the result:
(90 degrees)
(45 degrees)
I hope what I wrote was understandable enough, because I don't know how to explain it more clearlyIf anybody could shed some light on what I am doing wrong here, that would be awesome.
EDIT:
Changing Math.cos(this._viewAngle + (i * Math.PI / 180)); to Math.cos((this._viewAngle + i) * Math.PI / 180); results in this:
(90 degrees)
(45 degrees)

I think you're close with your update. As Sunil D points out, you presumably just want to align the vision cone so that it's centred at 90˚ from the vertical. In other words, starting from -_viewAngle * 0.5:
for (var i:Number = 0; i < this._viewAngle; i++)
{
var pointX:Number = (this._viewRange) * Math.cos((-this._viewAngle * 0.5 + i) * Math.PI / 180);
var pointY:Number = (this._viewRange) * Math.sin((-this._viewAngle * 0.5 + i) * Math.PI / 180);
this._rayHolder.graphics.lineTo(pointX, pointY);
this._rayHolder.graphics.moveTo(0, 0);
}
Edit: While these equations work for this application, the following reflect Flash's odd coordinate systems more accurately. Specifically, with positive x to the right, positive y downwards:
for (var i:Number = 0; i < this._viewAngle; i++)
{
var pointX:Number = (this._viewRange) * Math.sin((90 - this._viewAngle * 0.5 + i) * Math.PI / 180);
var pointY:Number = (this._viewRange) * -Math.cos((90 - this._viewAngle * 0.5 + i) * Math.PI / 180);
graphics.lineTo(pointX + 100, pointY + 100);
graphics.moveTo(100, 100);
}

Related

Draw a Pentagon with HTML 5 canvas

I need to draw a Pentagon with html 5 canvas in Javascript. Not much else to write here. I have tried looking it up, but a lot of the examples don't work correctly.
The pentagon starts at the 3oclock pos use rotation to change the start position in radians. ie To start at the top rotation is -90deg = -Math.PI / 2
function pentagon(x, y, radius, rotation){
for(var i = 0; i < 5; i ++){
const ang = (i / 5) * Math.PI * 2 + rotation;
ctx.lineTo(
Math.cos(ang) * radius + x,
Math.sin(ang) * radius + y
);
}
ctx.closePath();
}
ctx.beginPath();
pentagon(100,100,50,-Math.PI / 2);
ctx.fill();
ctx.stroke();

Rotating Angle Calculation AS3

I am writing a code where there are different rings on the stage, and a ball is rotating in one of these orbits. On click, the ball leaves its ring and travels normal to the ring. On its way if it hits another ring, it starts rotating in that ring from the point it hits the ring. I could successfully code the initial part of the code. but I am getting a problem when the ball hits another ring, it does not start from the location it hit. Instead it starts rotating in the ring from a different position. I hope I am clear with my doubt. It is somewhat similar to this game https://play.google.com/store/apps/details?id=com.drgames.orbit.jumper
here is my code in enter frame :
if(!isTravelling){
rad = Math.abs(angle * (Math.PI / 180)); // Converting Degrees To Radians
_ball.x = currOrbit.x + (currOrbit.width / 2) * Math.cos(rad); // Position The Orbiter Along x-axis
_ball.y = currOrbit.y + (currOrbit.width / 2) * Math.sin(rad); // Position The Orbiter Along y-axis
trace(_ball.x+" , "+_ball.y);
angle -= speed; // Object will orbit clockwise
_ball.rotation = (Math.atan2(_ball.y - currOrbit.y, _ball.x - currOrbit.x) * 180 / Math.PI) + 90;
}
for(var i = 0; i < orbits.length; i++){
if(orbits[i] != currOrbit){
if(ObjectsHit(orbits[i], _ball)){
currOrbit = orbits[i];
_ball.rotation = (Math.atan2(_ball.y - currOrbit.y, _ball.x - currOrbit.x) * 180 / Math.PI) + 90;
isTravelling = false;
stage.addEventListener(MouseEvent.CLICK, onClick);
}
}
}
if(isTravelling){
_ball.x += Math.cos(rad) * speed * 2;
_ball.y += Math.sin(rad) * speed * 2;
}
You seem to have forgotten to calculate the starting angle for the new orbit:
if(!isTravelling){
rad = Math.abs(angle * (Math.PI / 180)); // Converting Degrees To Radians
_ball.x = currOrbit.x + (currOrbit.width / 2) * Math.cos(rad); // Position The Orbiter Along x-axis
_ball.y = currOrbit.y + (currOrbit.width / 2) * Math.sin(rad); // Position The Orbiter Along y-axis
trace(_ball.x+" , "+_ball.y);
_ball.rotation = angle // no need for calculating the angle again
angle -= speed; // Object will orbit clockwise
}
for(var i = 0; i < orbits.length; i++){
if(orbits[i] != currOrbit){
if(ObjectsHit(orbits[i], _ball)){
currOrbit = orbits[i];
angle = (Math.atan2(_ball.y - currOrbit.y, _ball.x - currOrbit.x) * 180 / Math.PI) + 90; // Calculate the starting angle on the new orbit
_ball.rotation = angle // Set the balls rotation to the angle
isTravelling = false;
stage.addEventListener(MouseEvent.CLICK, onClick);
}
}
}
if(isTravelling){
_ball.x += Math.cos(rad) * speed * 2;
_ball.y += Math.sin(rad) * speed * 2;
}
This should fix it. Please note that you might have to add or subtract 90 degrees to your balls rotation (_ball.rotation = angle + 90) because im not 100% sure about that.

AS3 shooting in multiple directions

i am try trying to make space shooter game in which ship is able to rotate and shoot in all directions, now, i do know basics of trigonometry, but i stuck at this point and my brain seems to be frozen so i seek your help.
I have Ship.as and Turret.as , every ship contains some number of turrets, and this is loop that is responsible to create bullet for each turret on players input and its located in Ship.as.
for (var i:int = 0; i < turrets.length; i++)
{
var _pcos:Number = Math.cos(angle / 180 * Math.PI);
var _psin:Number = Math.sin(angle / 180 * Math.PI);
var bulletX:Number = center.x + turrets[i].distance * _pcos;
var bulletY:Number = center.y + turrets[i].distance * _psin;
var bullet:BulletBase = new bulletClass(bulletX, bulletY, angle);
layerBullets.add(bullet);
bullets.push(bullet);
}
variable center is point positioned in exact center of ships sprite, angle is ships rotation towards mouse, turret.distance is distance from center to turret
This is whats happening in Turret.as
public class Turret extends Point
{
private var ship:Ship;
public var distance:Number;
public var angle:Number;
/**
*
* #param x position with angle 0
* #param y position with angle 0
* #param distance distance from center of ship to turret
*/
public function Turret(x:Number = 0, y:Number = 0, ship:Ship = null)
{
super(x, y);
this.ship = ship;
this.x = x;
this.y = y;
var dx:Number = ship.center.x - x;
var dy:Number = ship.center.y - y;
angle = Math.atan2(dy, dx);
distance = Math.sqrt(dx * dx + dy * dy);
}
Now, what is happening with this code is that bullets seems like they are fired from same direction, only one bullet is behind.
I am not math expert and if anyone knows the answer i would really appreciate it.
var _pcos:Number = Math.cos((turret.angle + angle) / 180 * Math.PI);
var _psin:Number = Math.sin((turret.angle + angle) / 180 * Math.PI);
angle is angle of ship

find angle and velocity for a parabola that meet specific range

i'm a little ashamed to ask this, but i have tried a lot of different things and can't make it work.
i have a game that shots a bullet, i have made the code that calculates the parabola trajectory given a an angle and a velocity, but i'm trying to make the calculus needed to get the angle and velocity needed to reach X point (the user enemy tank) and i'm unable to make it work as i need.
my current code is:
var startingPointX:Number = globalCoord.x;
var startingPointY:Number = globalCoord.y;
var targetX:Number = tankPlayer.x;
var targetY:Number = tankPlayer.y;
//distance between user and enemy tank
var distanceTarget = Math.sqrt(( startingPointX - targetX ) * ( startingPointX - targetX ) + ( startingPointY - targetY ) * ( startingPointY - targetY ));
var fixedVel = (distanceTarget/10)*2;
var fixedG = bullet.g;
// launch angle
var o:Number = -(Math.asin((0.5 * Math.atan(fixedG * distanceTarget / fixedVel * fixedVel))) * 180 / Math.PI);
bullet.init(startingPointX, startingPointY, o, fixedVel);
and the functions in the bullet object that actually position the bullet in the parabola trajectory is:
public function init(x, y:Number, rot:Number, speed:Number) {
// set the start position
var initialMove:Number = 35.0;
this.x = x + initialMove * Math.cos(2 * Math.PI * rot / 360);
this.y = y + initialMove * Math.sin(2 * Math.PI * rot / 360);
this.rotation = rot;
//get speed
dx = speed * Math.cos(2 * Math.PI * rot / 360);
dy = speed * Math.sin(2 * Math.PI * rot / 360);
//animation
lastTime = getTimer();
addEventListener(Event.ENTER_FRAME,moveBullet);
}
public function moveBullet(event:Event)
{
//get the time passed
var timePassed:int = getTimer() - lastTime;
lastTime += timePassed;
//move bullet
dy += g * timePassed / 1000;
this.x += dx * timePassed / 1000;
this.y += dy * timePassed / 1000;
//bullet past the top of the screen
if (this.y < 0)
{
deleteBullet();
}
}
any help would be really useful, thanks ! :D
Regards,
Shadow.
If this is a ballistics problem in the sense that you project a particle from point A with velocity v at an angle theta and you want it to hit a point T where the y coordinates of A and T match (ie they lie on a plane perpendicular to the vector of gravitational force vector) then you can calculate the required angle and velocity from this equation (See your wiki link where this is defined):
R = (v * v * sin(2 * theta))/g
Here R is the distance travelled in the x direction from your start point A . The problem you are facing is you are trying to interpolate a parabola through just 2 points. There are an infinite amount of parabolas that will interpolate 2 points while the parabola through 3 points is unique. Essentially there are an infinite amount of choices for velocity and angle such that you can hit your target.
You will either need to fix the angle, or the velocity of the bullet in order to use the above equation to find the value you require. If not, you have an infinite number of parabolas that can hit your target.
The above assumes that air resistance is ignored.
EDIT : Thus if you know velocity v already you can get theta from simple rearrangement of the above :
( asin(g * R / (v * v)) ) / 2 = theta
Based on the suggestion from #mathematician1975 i resolved the code to this and works perfectly :D
var distanceTarget = startingPointX - targetX ;
var fixedVel = 100;
var fixedG = tmpB.g;
var o:Number = (0.5 * Math.atan((fixedG * distanceTarget / (fixedVel * fixedVel)))) * 180 / Math.PI;
//this is only necessary why the enemy tank is facing left
o -= 180;
what i made is:
set a fixed velocity as #mathematician1975 said, a lot bigger than before
the distance between starting and ending point is lineal and not using Pythagoras.
the -180 is just why the enemy tanks is facing left.
i hope someone would find it useful in the future :D
Regards,
Shadow.

How to create a polygon shape with flat sides in HTML5?

I'm using the following JS code to draw a 16-sided polygon:
context.beginPath();
var x_offset = 350;
var y_offset = 350;
var sides = 16;
var r = 300;
context.strokeStyle = "#000000";
for (i = 0; i < (sides); i++) {
x = x_offset + (r * Math.cos(2 * Math.PI * i / sides));
y = y_offset + (r * Math.sin(2 * Math.PI * i / sides));
context.moveTo(x, y);
x = x_offset + (r * Math.cos(2 * Math.PI * (i+1) / sides));
y = y_offset + (r * Math.sin(2 * Math.PI * (i+1) / sides));
context.lineTo(x, y);
}
context.stroke();
This is working fine, except that I want the polygon to have a 'flat' sides (top, bottom, left, right). In the picture below you see 2 polygons: the polygon with the red background color is what I want to achieve, the transparent polygon is the one generated by the code above.
Question: how can I generate a polygon with flat sides like the red one? Do I need to do a context.rotate()? I would prefer not too, to avoid all the translate() stuff.
You can just rotate by half of the stepping angle
context.beginPath();
for (var i = 0; i < sides; i++) {
var angle = 2 * Math.PI * (i + 0.5) / sides;
var x = x_offset + (r * Math.cos(angle));
var y = y_offset + (r * Math.sin(angle));
if (i == 0) context.moveTo(x, y);
else context.lineTo(x, y);
}
context.closePath();
I made some minor changes like using local variables and factoring out the angle computation (the added 0.5 is what is needed to have a vertical side).
Note that the polygon will have also horizontal sides only if the number of sides is a multiple of 4.