Intercept of sunrise on an Airplane - objective-c

I want to calculate predicted Time of closest approach between an aircraft and Sunrise or Sunset keeping in mind:
Airplane Flying South-westbound as sunrise approaches
Red line is the GreatCircle Track on airplane.
Blue circle is the Airplane.
moment of intersection with sunrise and the Airplane
1- sun Declination (latitude) and crossing Longitude is known , plus the radius of sunrise which is approx 5450 Nautical miles, so sunrise can be shown as a circle with known centre and radius.
2- I used 2D Vector code which did not work since Great circle Path can not be applies to XY plane.
2- The Airplane is flying on Great circle Track which is curved and Latitude change is not Linear, how can I use Airplane Speed as Velocity Vector if latitude change is not constant ?
/// Va - Velocity of circle A.
Va = new Vector2(450, 0);
I used c# code
/// Calculate the time of closest approach of two moving circles. Also determine if the circles collide.
///
/// Input:
/// Pa - Position of circle A.
/// Pb - Position of circle B.
/// Va - Velocity of circle A.
/// Vb - Velocity of circle B.
/// Ra - Radius of circle A.
/// Rb - Radius of circle B.
// Set up the initial position, velocity, and size of the circles.
Pa = new Vector2(150, 250);
Pb = new Vector2(600, 400);
Va = new Vector2(450, 0);
Vb = new Vector2(-100, -250);
Ra = 60;
Rb = 30;
/// Returns:
/// collision - Returns True if a collision occured, else False.
/// The method returns the time to impact if collision=true, else it returns the time of closest approach.
public float TimeOfClosestApproach(Vector2 Pa, Vector2 Pb, Vector2 Va, Vector2 Vb, float Ra, float Rb, out bool collision)
{
Vector2 Pab = Pa - Pb;
Vector2 Vab = Va - Vb;
float a = Vector2.Dot(Vab, Vab);
float b = 2 * Vector2.Dot(Pab, Vab);
float c = Vector2.Dot(Pab, Pab) - (Ra + Rb) * (Ra + Rb);
// The quadratic discriminant.
float discriminant = b * b - 4 * a * c;
// Case 1:
// If the discriminant is negative, then there are no real roots, so there is no collision. The time of
// closest approach is then given by the average of the imaginary roots, which is: t = -b / 2a
float t;
if (discriminant < 0)
{
t = -b / (2 * a);
collision = false;
}
else
{
// Case 2 and 3:
// If the discriminant is zero, then there is exactly one real root, meaning that the circles just grazed each other. If the
// discriminant is positive, then there are two real roots, meaning that the circles penetrate each other. In that case, the
// smallest of the two roots is the initial time of impact. We handle these two cases identically.
float t0 = (-b + (float)Math.Sqrt(discriminant)) / (2 * a);
float t1 = (-b - (float)Math.Sqrt(discriminant)) / (2 * a);
t = Math.Min(t0, t1);
// We also have to check if the time to impact is negative. If it is negative, then that means that the collision
// occured in the past. Since we're only concerned about future events, we say that no collision occurs if t < 0.
if (t < 0)
collision = false;
else
collision = true;
}
// Finally, if the time is negative, then set it to zero, because, again, we want this function to respond only to future events.
if (t < 0)
t = 0;
return t;
}
I accept any answer in any language:
JAVA , JS, Objective-C , Swift , C#.
All I am looking for is the Algorithm. and how to Represent the Airplane Speed as Velocity Vector2D or Vector3D.

Related

converting meter into pixel unit

i am trying to convert convert distance from meter to pixel in ros node, with pcl library and kinect xbox. I was using below code to access euclidean coordinates of every point from kinect inside ros node, which is in meter. But i wanted to get this measurments in pixel unit. What should i do?
void
cloud_cb (const sensor_msgs::PointCloud2ConstPtr& input)
{
pcl::PointCloud<pcl::PointXYZRGB> output;
pcl::fromROSMsg(*input,output );
for(int i=0;i<=400;i++)
{
for(int j=0;j<=400;j++)
{
p[i][j] = output.at(i,j);
ROS_INFO("\n p.z = %f \t p.x = %f \t p.y = %f",p[i][j].z,p[i][j].x,p[i][j].y);
}
}
sensor_msgs::PointCloud2 cloud;
pcl::toROSMsg(output,cloud);
pub.publish (cloud);
}
Here P[raw][col] is a Point structure which contains the x,y,z coordinates value in meter, which i want to convert in pixel unit. As i see the value of pixel unit is not constant, so cant use any value found in google.
I got similar question here: Kinect depth conversion from mm to pixels, but it has no solution.
There's a problem with trying to convert meters to pixels. Pixels aren't a standard unit. The physical size of 1 pixel varies on different devices depending on screen resolution and size of a screen.
If you know the resolution of the screen the conversion is still non-trivial.
const int L = 1920; //screen width
const int H = 1280; //screen height
for(int i=0;i<=L;i++){
for(int j=0;j<=H;j++){
p[i][j] = output.at(i*400/L,j*400/H);
}
}
Thus for every pixel you'll have a depth value corresponding to the depth value in the map. This will need some int conversion and improvement.

How do I randomize the starting direction of a ball in Spritekit?

I've started trying a few things with SpriteKit for Game Development. I was creating a brick breaking game. So I've run into a issue on how to randomize the starting direction of the ball.
My ball has the following properties
ball.physicsBody.friction = 0;
ball.physicsBody.linearDamping = 0;
ball.physicsBody.restitution = 1 ; //energy lost on impact or bounciness
To start at different direction during the gameplay, I've randomized the selection of the 4 vectors because I'm using the applyImpulse method to direct the ball in a particular direction and I need to make sure the ball does not go slow if the vector values are low.
int initialDirection = arc4random()%10;
CGVector myVector;
if(initialDirection < 2)
{
myVector = CGVectorMake(4, 7);
}
else if(initialDirection >3 && initialDirection <= 6)
{
myVector = CGVectorMake(-7, -5);
}
else if(initialDirection >6 && initialDirection <= 8)
{
myVector = CGVectorMake(-5, -8);
}
else
{
myVector = CGVectorMake(8, 5);
}
//apply the vector
[ball.physicsBody applyImpulse:myVector];
Is this the right way to do it? I tried using applyForce method but then, ball slowed down after the force was applied.
Is there any way I can randomize the direction and still maintain a speed for my ball ?
The basic steps
Randomly select an angle in [0, 2*PI)
Select the magnitude of the impulse
Form vector by converting magnitude/angle to vector components
Here's an example of how to do that
ObjC:
CGFloat angle = arc4random_uniform(1000)/1000.0 * M_PI_2;
CGFloat magnitude = 4;
CGVector vector = CGVectorMake(magnitude*cos(angle), magnitude*sin(angle));
[ball.physicsBody applyImpulse:vector];
Swift
let angle:CGFloat = CGFloat(arc4random_uniform(1000)/1000) * (CGFloat.pi/2)
let magnitude:CGFloat = 4
let vector = CGVector(x:magnitude * cos(angle), y:magnitude * sin(angle))
ball.physicsBody?.applyImpulse(vector)

Determining explosion radius damage - Circle to Rectangle 2D

One of the Cocos2D games I am working on has circular explosion effects. These explosion effects need to deal a percentage of their set maximum damage to all game characters (represented by rectangular bounding boxes as the objects in question are tanks) within the explosion radius. So this boils down to circle to rectangle collision and how far away the circle's radius is from the closest rectangle edge. I took a stab at figuring this out last night, but I believe there may be a better way. In particular, I don't know the best way to determine what percentage of damage to apply based on the distance calculated.
Note : All tank objects have an anchor point of (0,0) so position is according to bottom left corner of bounding box. Explosion point is the center point of the circular explosion.
TankObject * tank = (TankObject*) gameSprite;
float distanceFromExplosionCenter;
// IMPORTANT :: All GameCharacter have an assumed (0,0) anchor
if (explosionPoint.x < tank.position.x) {
// Explosion to WEST of tank
if (explosionPoint.y <= tank.position.y) {
//Explosion SOUTHWEST
distanceFromExplosionCenter = ccpDistance(explosionPoint, tank.position);
} else if (explosionPoint.y >= (tank.position.y + tank.contentSize.height)) {
// Explosion NORTHWEST
distanceFromExplosionCenter = ccpDistance(explosionPoint,
ccp(tank.position.x, tank.position.y + tank.contentSize.height));
} else {
// Exp center's y is between bottom and top corner of rect
distanceFromExplosionCenter = tank.position.x - explosionPoint.x;
} // end if
} else if (explosionPoint.x > (tank.position.x + tank.contentSize.width)) {
// Explosion to EAST of tank
if (explosionPoint.y <= tank.position.y) {
//Explosion SOUTHEAST
distanceFromExplosionCenter = ccpDistance(explosionPoint,
ccp(tank.position.x + tank.contentSize.width,
tank.position.y));
} else if (explosionPoint.y >= (tank.position.y + tank.contentSize.height)) {
// Explosion NORTHEAST
distanceFromExplosionCenter = ccpDistance(explosionPoint,
ccp(tank.position.x + tank.contentSize.width,
tank.position.y + tank.contentSize.height));
} else {
// Exp center's y is between bottom and top corner of rect
distanceFromExplosionCenter = explosionPoint.x - (tank.position.x + tank.contentSize.width);
} // end if
} else {
// Tank is either north or south and is inbetween left and right corner of rect
if (explosionPoint.y < tank.position.y) {
// Explosion is South
distanceFromExplosionCenter = tank.position.y - explosionPoint.y;
} else {
// Explosion is North
distanceFromExplosionCenter = explosionPoint.y - (tank.position.y + tank.contentSize.height);
} // end if
} // end outer if
if (distanceFromExplosionCenter < explosionRadius) {
/*
Collision :: Smaller distance larger the damage
*/
int damageToApply;
if (self.directHit) {
damageToApply = self.explosionMaxDamage + self.directHitBonusDamage;
[tank takeDamageAndAdjustHealthBar:damageToApply];
CCLOG(#"Explsoion-> DIRECT HIT with total damage %d", damageToApply);
} else {
// TODO adjust this... turning out negative for some reason...
damageToApply = (1 - (distanceFromExplosionCenter/explosionRadius) * explosionMaxDamage);
[tank takeDamageAndAdjustHealthBar:damageToApply];
CCLOG(#"Explosion-> Non direct hit collision with tank");
CCLOG(#"Damage to apply is %d", damageToApply);
} // end if
} else {
CCLOG(#"Explosion-> Explosion distance is larger than explosion radius");
} // end if
} // end if
Questions:
1) Can this circle to rect collision algorithm be done better? Do I have too many checks?
2) How to calculate the percentage based damage? My current method generates negative numbers occasionally and I don't understand why (Maybe I need more sleep!). But, in my if statement, I ask if distance < explosion radius. When control goes through, distance/radius must be < 1 right? So 1 - that intermediate calculation should not be negative.
Appreciate any help/advice
EDIT
My occasional negative result was due to a misplaced parenthesis.
damageToApply = (1 - (distanceFromExplosionCenter/explosionRadius)) * explosionMaxDamage;
Still looking for input on how to calculate explosion radius damage.
You can check the distance of the objects using ccpDistance:
float distance = ccpDistance(sprite1.position, sprite2.position);
I think the ccpDistance will always return a positive value. But if its't, then get the absolute value: fabsf(distance)

Explain code in Kinect SDK

I am working with Kinect and reading example from DepthWithColor-D3D, has some code but i don't understand yet.
// loop over each row and column of the color
for (LONG y = 0; y < m_colorHeight; ++y)
{
LONG* pDest = (LONG*)((BYTE*)msT.pData + msT.RowPitch * y);
for (LONG x = 0; x < m_colorWidth; ++x)
{
// calculate index into depth array
int depthIndex = x/m_colorToDepthDivisor + y/m_colorToDepthDivisor * m_depthWidth;
// retrieve the depth to color mapping for the current depth pixel
LONG colorInDepthX = m_colorCoordinates[depthIndex * 2];
LONG colorInDepthY = m_colorCoordinates[depthIndex * 2 + 1];
How to calculate the value of colorInDepthX and colorInDepthY as above code?
colorInDepthX and colorInDepthY is a mapping between the depth and color images so that they will align. Because the Kinect's cameras are slightly offset from each other their field of views are not lined up perfectly.
m_colorCoordinates is defined at the top of the file as such:
m_colorCoordinates = new LONG[m_depthWidth*m_depthHeight*2];
This is a single dimension array representing a 2-dimensional image, it is populated just above the code block you post in your question:
// Get of x, y coordinates for color in depth space
// This will allow us to later compensate for the differences in location, angle, etc between the depth and color cameras
m_pNuiSensor->NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution(
cColorResolution,
cDepthResolution,
m_depthWidth*m_depthHeight,
m_depthD16,
m_depthWidth*m_depthHeight*2,
m_colorCoordinates
);
As described in the comment, this is running an calculation provided by the SDK to map the color and depth coordinates onto each other. The result is placed inside of m_colorCoordinates.
colorInDepthX and colorInDepthY are simply values within the m_colorCoordinates array that are being acted upon in the current cycle of the loop. They are not "calculated", per se, but just point to what already exists in m_colorCoordinates.
The function that handles the mapping between color and depth images is explained in the Kinect SDK at MSDN. Here is a direct link:
http://msdn.microsoft.com/en-us/library/jj663856.aspx

Android Location.distanceTo

I wrote a function to determine the distance between two GPS locations.
public float latDistance(Location newLocal){
// get distance
Location tempLocal1 = new Location("ref1");
Location tempLocal2 = new Location("ref2");
// get lon difference
tempLocal1.setLatitude(local.getLatitude());
tempLocal1.setLongitude(0);
tempLocal1.setAltitude(0);
tempLocal2.setLatitude(newLocal.getLatitude());
tempLocal2.setLongitude(0);
tempLocal2.setAltitude(0);
return tempLocal2.distanceTo(tempLocal1);
}
My question is, will this ever return a negative value? my goal is to get a distance that reflects whether they moved north or south.. so if they move south from the starting location i want a negative value, and if north a positive?
It seems that i am always getting a positive number, but i can't tell if that is just my innaccurate gps readings
EDIT:
my code now looks like this.. and i know it irregular to ask people to comment on the logic, but its a difficult thing to test as it relies on a gps signal and to test i have to basically go out side and get a good signal, which pulls me away from my IDE and LogCat..
public float getLattitudeDistance(Location newLocal){
// get distance
Location tempLocal1 = new Location("ref1");
Location tempLocal2 = new Location("ref2");
// get lon difference
tempLocal1.setLatitude(local.getLatitude());
tempLocal1.setLongitude(0);
tempLocal1.setAltitude(0);
tempLocal2.setLatitude(newLocal.getLatitude());
tempLocal2.setLongitude(0);
tempLocal2.setAltitude(0);
if(local.getLatitude()>newLocal.getLatitude()){
return -tempLocal2.distanceTo(tempLocal1);
}else{
return tempLocal2.distanceTo(tempLocal1);
}
}
public float getLongitudeDistance(Location newLocal){
// get distance
Location tempLocal1 = new Location("ref1");
Location tempLocal2 = new Location("ref2");
// get lon difference
tempLocal1.setLatitude(0);
tempLocal1.setLongitude(local.getLongitude());
tempLocal1.setAltitude(0);
tempLocal2.setLatitude(0);
tempLocal2.setLongitude(newLocal.getLongitude());
tempLocal2.setAltitude(0);
if(local.getLongitude()>newLocal.getLongitude()){
return -tempLocal2.distanceTo(tempLocal1);
}else{
return tempLocal2.distanceTo(tempLocal1);
}
}
does that seem right?
No, distances are never negative!
For south movement you may extend your code :
float distance = tempLocal2.distanceTo(tempLocal1);
// lat1: previous latitude
// lat2: current latitude
if (lat2 < lat1) {
// movement = south
distance = -distance:
} else {
// movement = north or parallel aeqator or not moving
}
return distance
Although i reccomend to separate distance and South Movement (in future maybe you would like to detect an East-West movement, too)