I am working on an application in Android, wherein I have to get android.graphics.path values and compare them.
Consider the following images :
and
The first image shows a straight line and the generated Path value. Similarly, the second image,also shows a similar straight line, with a different Path value.
I'm unable to understand the value that is generated. Can anyone explain as to what exactly the generated values mean? Can I approximately take a wild guess about a path value from the screen coordinates?
Also, in my application, I would like to compare path values. The lines shown in the above figure are similar. And in my application, I would like to compare them and render them as same lines. And I'm not just going to compare lines, there'll be curves and all such drawable shapes. For comparison do I first have to normalize my path values (maybe calling getMatrix for my current canvas?), so as to have the same effect for different screen sizes?
There is one other way of comparison that will be much simpler,finding centroids of the paths of figures. Obviously lines will have a centroid at a different position compared to curves,etc. But this sort of comparison won't be so accurate. I wanted to store some value and then compare the generated path value to the stored value, along with comparing the centroids, so as to have a better accuracy. But for that, I need to understand the generated path values!
Please help or guide! Thanks! :-)
Edit:
The code that I'm using for converting my path values to String. My path values are stored in an ArrayList (called pointsToDraw ). Here's the code :
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
synchronized(pointsToDraw){
for(Path path : pointsToDraw)
{
stringPoints.add(String.valueOf(path));
}
}
TextView b1Text = (TextView) findViewById(R.id.GText);
for(String s : stringPoints)
{
b1Text.setText(s);
}
}
A Path object is an object that encapsulates a series of geometric paths. If you want to programmatically compare one path to another, then the place I think you have to start is to use PathMeasure on that Path object in order to pull out all of the co-ordinates. Using PathMeasure you can obtain a series of co-ordinates that the path follows, by supplying a distance argument.
PathMeasure
Then, in order to determine whether one given path is similar to another in terms of the size and its path along the screen, I would perhaps suggest using PathMeasure on them both and comparing the co-ordinates they produce given incremental distance arguments. Then use some comparison algorithm, which may be as simple as determining whether each set of compared co-ordinates are within a distance from each other (with relative starting co-ordinates taken into account).
So I can't help with the algorithm you would use, but as a starting point, I think it's PathMeasure that you have to use in order to inspect and analyse the data within the Path to begin with. Or, you might want to render them to bitmap and use some kind of image recognition library to compare those bitmaps, perhaps?
You can't really make a string for that object I think, so you get the default value: If you check out the manual you see that it is actually the same as
getClass().getName() + '#' + Integer.toHexString(hashCode())
or, in their words,
The unsigned hexadecimal representation of the hash code of the object.
It's just a hashed value of the object, and has no direct recognisable connection to for instance any features of the Path (location etc). If you really want to know how it is made you can find the hashCode() function of that object, but I suspect you won't see anything interesting for this question.
To be clear, when you say you want to compare "path values" you seem to imply that you want to compare above printed values. I don't see how you would want to need that. You probably want to check if 2 separately drawn/created lines are the same. You cannot use this hash for that purpose, you need to use the actual values like start/stop/angle/or something like that. (I'm not sure what members are present in a path, but you can look that up)
Related
I'm actually using Math.sin() in my android app to calculate a sinus of a given angle (using Math.toRadians(angle_in_degrees)). For exemple when I want to get the Math.cos(90) which is 0, the result is 6.123233... E-17. Thanks you.
For floating point numbers, the system can often only approximate their values. For instance, the system would return something like 0.333333 for the expression (1.0 / 3). The number of 3s after the decimal point will be different depending on whether you're a floats or doubles, but it will still be limited to some finite length.
If you're just displaying the value, then you can limit the number of digits using something like String.format("%0.2f", value) or by rounding it using one of the rounding functions such as Math.round().
The tricky part comes when you need to compare the value to something. You can't just use if (value == some_constant) or even if (value == some_variable). At minimum, you usually have to use something like if (Math.abs(value - some_constant) < 0.001). The actual value of the '0.001' depends on the needs of your particular application and is customarily defined as a named constant.
For more complicated needs, you can implement the algorithm in the Floating-Point Guide.
You're getting back an approximation from Math.cos(Math.toRadians(90)) which is
6.123233... E-17 == 0.00000000000000006123233... which is basically 0
The following link should help clear things up as far as the precision of doubles/floats in programming.
http://www.java67.com/2015/09/float-and-double-value-comparison-in-java-use-relational.html
I am getting a kmz-file from a webservice, which I use for geofencing.
The app is responsible to check whether the gps-location of the phone is within the geofence, or not.
I don't really know how the kmz-file will be structured (I am not creating it), but I think the coordinates might look like this:
<coordinates>
-112.2550785337791,36.07954952145647,2357
-112.2549277039738,36.08117083492122,2357
-112.2552505069063,36.08260761307279,2357
-112.2564540158376,36.08395660588506,2357
-112.2644963846444,36.08627897945274,2357
-112.2656969554589,36.08649599090644,2357
</coordinates>
How can I check if the gps-coordinates of my phone are within the geofence (the example above is only a line, it should be a closed area, for example a rectangle)? Right now I can't really think of how to do that.
And what library should be used to access the kmz-files?
First, for geofencing, download the sample from here and read the documentation. And I don;t know about kmz file. But if you can get the string from it(using file reading) and know its structure, then you can easily parse it. If the format is like you mentioned, then you can get the values by following method:
Split the string on coordinates (including <>). You will get a string array. Take the string at index 1.
Split this string on /coordinates (including <>). You will get another string array. Take the string at index 0.
Now split this string on ",". You will get an array of strings again! Now at indexes 0,3,6... are latitudes and at indexes 1,4,7... are longitudes and at indexes 2,5,8... are the third number in the data you mentioned.
I need to set the direction value when capture a image from the camera in a tag inside the image. I try for example:
exif.setAttribute("GPSImgDirectionRef","T");
exif.setAttribute("GPSImgDirection","142.2");
with no success.
Any idea?
Thks.
I came into a solution for this issue recently, if someone needs it:
According to ExifInterface documentation the attribute using the tag TAG_GPS_IMG_DIRECTION expects a "rational" value. But as far as I could understand it's source code, it validates the inserted value firstly by checking if there's a "/" char in the string, and after that get the numbers before and after the "/" to generate a double value, and just when it can be converted to a double value this attribute will be added to the image file.
So basically to make it work, instead of sending a double value as your attribute, you need to send a fraction.
As a suggestion, making a fraction out of a double could be easily done using Apache Commons Math Lib - Fraction. It would be something like this:
Fraction azimuthAsFraction = new Fraction(azimuthAsDouble);
exif.setAttribute(TAG_GPS_IMG_DIRECTION, String.valueOf(azimuthAsFraction));
This way your azimuth value should be added to the image file metadata.
I'm looking for a way to compare 2 strings partial. I need to clear this with an example.
The base string is "equality".
The string I need to check is spelled wrong: "equallaty". I want to conform this is partially correct so the input, even not right in a grammar way, is the same as the base string.
Now I can of course parse the string to an char array. Now I can check every single character, but if I check the first 4 characters they will be right, the rest will be wrong even if there are only 2 mistakes. So the check I want to use is that a minimum of 70 procent of the characters should match.
Is anyone able to help me get on the right track?
Compare the strings with an edit-distance metric like the Levenshtein distance. Such a metric basically counts the number of changes needed to make the strings equal. If the number of changes is small relative to the total size of the string, then you can consider the strings similar.
i have a problem with double values i need to store in an android homed sqlite database. since these double values represent gps values (lat & lng), i really NEED an absolute precision down to the 9th number after the comma.
now i have a table like this:
CREATE TABLE x REAL lng;
and insert sth (hardcoded) like:
INSERT INTO x lng = '1.0';
and when reading lng from this table into some (java) double variable, i get a value like "0.999956837" - this renders the values pretty useless to me.
is there a way to enforce the precision i need other than storing the values as "text" fields (what would make expensive casts neccessary) or storing them as integers (meaning i need to multiply/divide at each write/read-op)?
SQLite is typeless, that means all representation is written as text, probably the wrapper api does some converts you don't know of, that you get those results.
If you need to store the data as string do it.
Just when you read out the double make sure you saved in the right format, you can use getDouble on the column.
double has about 17 decimal digits of precision, so if 9 digits is what you need, there should be no problem (assuming that you don't do any complex calculations on those values). Just make sure you never end up using float, because that has only about 7 digits of precision.
You should also make sure you understand how binary floating-point works, and that it will always result in seemingly "round" values becoming slightly off - which simply does not matter for most applications (including yours) as long as it happes somewhere in the 17th decimal digit. See that link also for alternatives for applications where it does matter.