Making sense of a list of GPS values in an iOS application - ios7

I have a web service that interfaces with the google maps API to generate a polygon on a google map. The service takes the GPS values and stores them for retrieval.
The problem is that when I try and use these values on my iPhone app the MKPolyline is just either a mess or a bunch of zig-zag lines.
Is there a way to make sense of these values so I can reconstruct the polygon?
My current code looks like this
private void GenerateMap()
{
var latCoord = new List<double>();
var longCoord = new List<double>();
var pad = AppDelegate.Self.db.GetPaddockFromCrop(crop);
mapMapView.MapType = MKMapType.Standard;
mapMapView.ZoomEnabled = true;
mapMapView.ScrollEnabled = false;
mapMapView.OverlayRenderer = (m, o) =>
{
if (o.GetType() == typeof(MKPolyline))
{
var p = new MKPolylineRenderer((MKPolyline)o);
p.LineWidth = 2.0f;
p.StrokeColor = UIColor.Green;
return p;
}
else
return null;
};
scMapType.ValueChanged += (s, e) =>
{
switch (scMapType.SelectedSegment)
{
case 0:
mapMapView.MapType = MKMapType.Standard;
break;
case 1:
mapMapView.MapType = MKMapType.Satellite;
break;
case 2:
mapMapView.MapType = MKMapType.Hybrid;
break;
}
};
if (pad.Boundaries != null)
{
var bounds = pad.Boundaries.OrderBy(t => t.latitude).ThenBy(t => t.longitude).ToList();
foreach (var l in bounds)
{
double lat = l.latitude;
double lon = l.longitude;
latCoord.Add(lat);
longCoord.Add(lon);
}
if (latCoord.Count != 0)
{
if (latCoord.Count > 0)
{
var coord = new List<CLLocationCoordinate2D>();
for (int i = 0; i < latCoord.Count; ++i)
{
var c = new CLLocationCoordinate2D();
c.Latitude = latCoord[i];
c.Longitude = longCoord[i];
coord.Add(c);
}
var line = MKPolyline.FromCoordinates(coord.ToArray());
mapMapView.AddOverlay(line);
mapMapView.SetVisibleMapRect(line.BoundingMapRect, true);
}
}
}
}
MKPolygon / MKPolygonRenderer gives the same sort of random line mess. The OrderBy LINQ makes no difference other than to make the random lines a zig-zag going up or down the view.

Since you don't know the order the points were captured in, you can't trace the actual path traveled around the perimeter of the paddock; this is why your polylines are turning into silly-walks all over the map. Lacking that information, you can at best make an educated guess.
Some possible heuristics you might want to try:
Take the average of all the points to get a "somewhere in the middle" point, then order by atan2(l.latitude - middle.latitude, l.longitude - middle.longitude). (Be careful, atan2 is undefined at (0, 0)!)
Take the convex hull of the points captured: for a relatively small number of points you can get away with the simple quadratic time Jarvis's march. This has the approximate effect of wrapping a notional rubber band around the outside of the map push-pins by discarding points that would form concavities, and should also give you the order of the remaining points.

Related

game maker GML twin stick shooter analogue controller

I am trying to make a twin stick shooter but I cannot get right analogue stick to shoot in the correct direction. Here is the code I have the weapon sits on top of the player and rotates. It all works fine just need to know how to get the correct angle of the right stick and fire a bullet in that direction.
//set depth
depth = -y + obj_player.y_off_set - 1;
//analog left stick face direction
var h_point = gamepad_axis_value(0, gp_axisrh);
var v_point = gamepad_axis_value(0, gp_axisrv);
if ((h_point != 0) || (v_point != 0))
{
var pdir = point_direction(0, 0, h_point, v_point);
var dif = angle_difference(pdir, image_angle);
image_angle += median(-20, dif, 20);
}
//flips gun when turning
if(gamepad_axis_value(0, gp_axisrh) < -0.5)
{
image_yscale = -1;
}else if (gamepad_axis_value(0, gp_axisrh) > 0.5)
{
image_yscale = 1;
}
//fireing
fire = gamepad_button_check_pressed(0, gp_shoulderr) && alarm[0] <= 0;
if(fire)
{
var face = point_direction(0, 0, gp_axisrh, gp_axisrv);
var p = instance_create(x, y, obj_projectile);
var xforce = lengthdir_x(20, face*90);
var yforce = lengthdir_x(20, face*90);
p.creator = id;
with (p){
physics_apply_impulse(x, y, xforce, yforce);
}
as this question is a couple months old, I imagine you found the solution to your problem, but hopefully this answer can help anyone else stuck on the issue.
Based on the code snippet you provided, it looks like if you remove the *90 from the lengthdir_ functions, your code should work.
Here is the code I wrote in my game to get 360 degree shooting working with the right analog stick (this code lives in the step event of the Player object):
if (shooting) {
bullet = instance_create(x, y, Bullet);
with (bullet) {
haxis = gamepad_axis_value(0, gp_axisrh);
vaxis = gamepad_axis_value(0, gp_axisrv);
dir = point_direction(0, 0, haxis, vaxis);
physics_apply_impulse(x, y, lengthdir_x(50, gp_axisrh), lengthdir_y(50, dir));
}
}
This particular thread on the GameMaker community forums was quite helpful as I researched how to solve this issue in my game.

Windows Store App: set an image as a background for an UI element

Sorry for asking a really basic question, but it's probably the first time for a number of years I feel really confused.
Windows provides two set of controls: Windows.UI.Xaml namespace (I thinks this is referred as Metro), used for Windows Store Apps, and System.Windows (WPF) for Desktop.
Since I am going to develop Windows Store Apps mainly for Windows 8.1 and Windows 10 phones, I will have to stick to Windows.UI.Xaml, and this has not only a separate set of UI elements, but also separate set of bitmaps, brushes, etc. (Windows.UI.Xaml.Media vs System.Windows.Media).
I found that Windows.UI.Xaml provides a very limited support for graphics, much less than provided by WPF, Android or (even!) iOS platform. To start with, I got stuck with a simple task: tiling a background!
Since Windows.UI.Xaml.Media.ImageBrush do not support tiling, I wanted to to do that "manually". Some sites suggest making numerous number of children, each holding a tile. Honestly, it looks as a rather awkward approach to me, so I decided to do it in what appears a more natural way: create an off-screen tiled image, assign it to a brush and assign the brush as the background for a panel.
The tiling code is rather straightforward (it probably has mistakes, possibly won't even not run on a phone, because of some unavailable classes used).
int panelWidth = (int) contentPanel.Width;
int panelHeight = (int) contentPanel.Height;
Bitmap bmpOffscreen = new Bitmap(panelWidth, panelHeight);
Graphics gOffscreen = Graphics.FromImage(bmpOffscreen);
string bmpPath = Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path, "Assets/just_a_tile.png");
System.Drawing.Image tile = System.Drawing.Image.FromFile(bmpPath, true);
int tileWidth = tile.Width;
int tileHeight = tile.Height;
for (int y = 0; y < panelHeight; y += tileHeight)
for (int x = 0; x < panelWidth; x += tileWidth)
gOffscreen.DrawImage(tile, x, y);
Now I presumably have the tiled image in bmpOffscreen. But how assign it to a brush? To do that I need to convert Bitmap to BitmapSource, while I couldn't find something similar to System.Windows.Imaging.CreateBitmapSourceFromHBitmap available for WPF structure!
Well, first of all System.Drawing namespace is not available in Windows Universal Platform, so you won't be able to use Bitmap class
But, all hope is not lost - you can use
Windows.UI.Xaml.Media.Imaging.WriteableBitmap
If you look at example included on this page, you will see that at one point image data is extracted to a byte array - all you need to do is copy it according to your needs
Please let me know if you want me to include a complete code sample.
Edit:
StorageFile file = await StorageFile.GetFileFromPathAsync(filePath);
Scenario4WriteableBitmap = new WriteableBitmap(2000, 2000);
// Ensure a file was selected
if (file != null)
{
using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
int columns = 4;
int rows = 4;
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
// Scale image to appropriate size
BitmapTransform transform = new BitmapTransform()
{
ScaledHeight = Convert.ToUInt32(Scenario4ImageContainer.Height),
ScaledWidth = Convert.ToUInt32(Scenario4ImageContainer.Width)
};
PixelDataProvider pixelData = await decoder.GetPixelDataAsync(
BitmapPixelFormat.Bgra8, // WriteableBitmap uses BGRA format
BitmapAlphaMode.Straight,
transform,
ExifOrientationMode.IgnoreExifOrientation, // This sample ignores Exif orientation
ColorManagementMode.DoNotColorManage);
// An array containing the decoded image data, which could be modified before being displayed
byte[] sourcePixels = pixelData.DetachPixelData();
// Open a stream to copy the image contents to the WriteableBitmap's pixel buffer
using (Stream stream = Scenario4WriteableBitmap.PixelBuffer.AsStream())
{
for (int i = 0; i < columns * rows; i++)
{
await stream.WriteAsync(sourcePixels, 0, sourcePixels.Length);
}
}
}
// Redraw the WriteableBitmap
Scenario4WriteableBitmap.Invalidate();
Scenario4Image.Source = Scenario4WriteableBitmap;
Scenario4Image.Stretch = Stretch.None;
}
Thank you, Arkadiusz. Since Australian time goes slightly ahead of Europe,
I had an advantage and seen the code before you posted it. I downloaded
MSDN XAML images sample and it helped me a lot. I gave a +1 to you but someone apparently put -1, so it compensated each other. Don't be upset I get -1 so often, that I stopped paying attention on that :)
So I've managed to do tiling with Windows Universal Platform! On my Lumia 532 phone it works magnifique. I felt like re-inventing a wheel, because all this stuff must be handled by SDK, not by a third-party developer.
public static async Task<bool> setupTiledBackground(Panel panel, string tilePath)
{
Brush backgroundBrush = await createTiledBackground((int)panel.Width, (int)panel.Height, TilePath);
if (backgroundBrush == null) return false;
panel.Background = backgroundBrush;
return true;
}
private static async Task<Brush> createTiledBackground(int width, int height, string tilePath)
{
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///" + tilePath));
byte[] sourcePixels;
int tileWidth, tileHeight;
using (IRandomAccessStream inputStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
if (inputStream == null) return null;
BitmapDecoder tileDecoder = await BitmapDecoder.CreateAsync(inputStream);
if (tileDecoder == null) return null;
tileWidth = (int)tileDecoder.PixelWidth;
tileHeight = (int) tileDecoder.PixelHeight;
PixelDataProvider pixelData = await tileDecoder.GetPixelDataAsync(
BitmapPixelFormat.Bgra8, // WriteableBitmap uses BGRA format
BitmapAlphaMode.Straight,
new BitmapTransform(),
ExifOrientationMode.IgnoreExifOrientation,
ColorManagementMode.DoNotColorManage);
sourcePixels = pixelData.DetachPixelData();
// fileStream.Dispose();
}
WriteableBitmap backgroundBitmap = new WriteableBitmap(width, height);
int tileBmpWidth = tileWidth << 2;
int screenBmpWidth = width << 2;
int tileSize = tileBmpWidth * tileHeight;
int sourceOffset = 0;
using (Stream outputStream = backgroundBitmap.PixelBuffer.AsStream())
{
for (int bmpY=0; bmpY < height; bmpY++) {
for (int bmpX = 0; bmpX < screenBmpWidth; bmpX += tileBmpWidth)
await outputStream.WriteAsync(sourcePixels, sourceOffset, Math.Min(screenBmpWidth - bmpX, tileBmpWidth));
if ((sourceOffset += tileBmpWidth) >= tileSize)
sourceOffset -= tileSize;
}
}
ImageBrush backgroundBrush = new ImageBrush();
backgroundBrush.ImageSource = backgroundBitmap; // It's very easy now!
return backgroundBrush; // Finita la comédia!
}
Just one remark: if you do it on form start, you should not wait for it.
This doesn't work:
public MainPage()
{
this.InitializeComponent();
bool result = setupTiledBackground(contextPanel, TilePath).Result;
}
This works:
private Task<bool> backgroundImageTask;
public MainPage()
{
this.InitializeComponent();
backgroundImageTask = setupTiledBackground(contextPanel, TilePath);
}

Find the point of a line after which it dissapears - three.js

I want to position x,y,z labels (sprites) on the axis I have in my scene. The problem is that zooming with the camera , should result to also moving the particles analogously so they stay in the side of the "screen".
So I just want to find a way to always know where the lines of x,y,z are out of the camera to update the labels' positions :
fiddle (here they are just static).
the pseudocode of what I might need to acheve that :
function update() {
var pointInLinePosition = calculateLastVisiblePointOfXline();
xSprite.position.set(pointInLinePosition.x, pointInLinePosition.y, pointInLinePosition.z);
}
function calculateLastVisiblePointOfXline(){
}
I found a solution which is satisfying enough (for me at least) but not perfect.
Firstly I create a frustum using the scene's camera :
var frustum = new THREE.Frustum();
frustum.setFromMatrix( new THREE.Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse ) );
Then, I check if any of the planes of the frustum intersects with any of the lines I have in the scene :
for (var i = frustum.planes.length - 1; i >= 0; i--) {
var py = frustum.planes[i].intersectLine( new THREE.Line3( new THREE.Vector3(0,0,0), new THREE.Vector3(1000,0,0) ) ) ;
if(py !== undefined) {
ySprite.position.x = py.x-1 ;
}
var px = frustum.planes[i].intersectLine( new THREE.Line3( new THREE.Vector3(0,0,0), new THREE.Vector3(0,0,1000) ) ) ;
if(px !== undefined) {
xSprite.position.z = px.z-1 ;
}
};
If there is an intersection, I update the labels' position using the return value of the intersectLine() which is the point of intersection.
This is the updated fiddle : fiddle
I hope that helps. In my case it fit.
A correct test for intersections also has to make sure that the intersection point is actually within the frustum as the frustum planes extend indefinitely, potentially leading to false positive intersections.
One naive way of validating intersections, is checking the distance of the intersection to all planes. If the distance is greater or equal to zero, the point is within the frustum.
Adjusted code snipped from ThanosSar's answer:
const intersect = point => frustum.planes
.map(plane =>
plane.intersectLine(new THREE.Line3(new THREE.Vector3(0, 0, 0), point))
)
.filter(sect => sect != null)
.filter(sect => frustum.planes.every(plane => plane.distanceToPoint(sect) >= -0.000001))[0];
const iy = intersect(new THREE.Vector3(1000, 0, 0));
if (iy != null)
ySprite.position.x = iy.x - 1;
const ix = intersect(new THREE.Vector3(0, 0, 1000));
if (ix != null)
xSprite.position.z = ix.z - 1;
(The comparison is with >= -0.000001 to account for floating point rounding errors)
Fiddle

Rescale X across all plots in ZedGraph

I can successfully zoom x-only across all plots using the following code:
zg1.IsEnableHZoom = true;
zg1.IsEnableVZoom = false;
zg1.IsSynchronizeXAxes = true;
foreach (GraphPane gp in zg1.MasterPane.paneList)
{
> //What code can I put here?
}
My problem is that using this code, the Y-axis remains at a max and min based on the original view of the data. I want the Y-axis to autoscale so that the max and min is ONLY based on the data visible due to the x-axis zoom (per graph pane, of course). Is there some command, or brute force method, that I can use on each of the graph panes in the for loop shown above? Thanks ahead of time for anyone's help.
You can use this in the loop (assuming X Axis scale MinAuto and MaxAuto are false)
foreach (GraphPane gp in zg1.MasterPane.paneList)
{
gp.YAxis.Scale.MinAuto = true;
gp.YAxis.Scale.MaxAuto = true;
// This will force ZedGraph to calculate the Min and the Max of the Y axis
// based on the X axis visible range
gp.IsBoundedRanges = true;
}
zg1.MasterPane.AxisChange();
I had the same problem before and could not find a way other than to inspect all the curve points.
I added an event handler to the Paint event to do this, I'm sure there are ways this can be optimized.
Something like this:
private void graph_Paint(object sender, PaintEventArgs e)
{
double min = Double.MaxValue;
double max = Double.MinValue;
CurveItem curve = graph.GraphPane.CurveList[0];
for (int i = 0; i < curve.Points.Count; i++)
{
if (curve.Points[i].X > graph.GraphPane.XAxis.Scale.Min &&
curve.Points[i].X < graph.GraphPane.XAxis.Scale.Max)
{
min = Math.Min(curve.Points[i].Y, min);
max = Math.Max(curve.Points[i].Y, max);
}
}
if (min != Double.MaxValue)
{
graph.GraphPane.XAxis.Scale.Min = min;
graph.GraphPane.XAxis.Scale.Max = max;
}
}

point light illumination using Phong model

I wish to render a scene that contains one box and a point light source using the Phong illumination scheme. The following are the relevant code snippets for my calculation:
R3Rgb Phong(R3Scene *scene, R3Ray *ray, R3Intersection *intersection)
{
R3Rgb radiance;
if(intersection->hit == 0)
{
radiance = scene->background;
return radiance;
}
...
// obtain ambient term
... // this is zero for my test
// obtain emissive term
... // this is also zero for my test
// for each light in the scene, obtain calculate the diffuse and specular terms
R3Rgb intensity_diffuse(0,0,0,1);
R3Rgb intensity_specular(0,0,0,1);
for(unsigned int i = 0; i < scene->lights.size(); i++)
{
R3Light *light = scene->Light(i);
R3Rgb light_color = LightIntensity(scene->Light(i), intersection->position);
R3Vector light_vector = -LightDirection(scene->Light(i), intersection->position);
// check if the light is "behind" the surface normal
if(normal.Dot(light_vector)<=0)
continue;
// calculate diffuse reflection
if(!Kd.IsBlack())
intensity_diffuse += Kd*normal.Dot(light_vector)*light_color;
if(Ks.IsBlack())
continue;
// calculate specular reflection
... // this I believe to be irrelevant for the particular test I'm doing
}
radiance = intensity_diffuse;
return radiance;
}
R3Rgb LightIntensity(R3Light *light, R3Point position)
{
R3Rgb light_intensity;
double distance;
double denominator;
if(light->type != R3_DIRECTIONAL_LIGHT)
{
distance = (position-light->position).Length();
denominator = light->constant_attenuation +
(light->linear_attenuation*distance) +
(light->quadratic_attenuation*distance*distance);
}
switch(light->type)
{
...
case R3_POINT_LIGHT:
light_intensity = light->color/denominator;
break;
...
}
return light_intensity;
}
R3Vector LightDirection(R3Light *light, R3Point position)
{
R3Vector light_direction;
switch(light->type)
{
...
case R3_POINT_LIGHT:
light_direction = position - light->position;
break;
...
}
light_direction.Normalize();
return light_direction;
}
I believe that the error must be somewhere in either LightDirection(...) or LightIntensity(...) functions because when I run my code using a directional light source, I obtain the desired rendered image (thus this leads me to believe that the Phong illumination equation is correct). Also, in Phong(...), when I computed the intensity_diffuse and while debugging, I divided light_color by 10, I was obtaining a resulting image that looked more like what I need. Am I calculating the light_color correctly?
Thanks.
Turned out I had no error. The "final image" I was comparing my results to wasn't computed correctly.