I wonder if someone can help me get total route distance in Heremap iOS sdk. According to the document, the following should do it, but I only ever get back values that borders on infinity, and that' just evil. Can someone please provide a working example? I am running this in the simulator but that shouldn't really matter.
unsigned long long distance_ul = [NMANavigationManager sharedNavigationManager].distanceToDestination;
NMAUint64 distance_i64 = [NMANavigationManager sharedNavigationManager].distanceToDestination;
Your second usage NMAUint64 distance = [NMANavigationManager sharedNavigationManager].distanceToDestination; is ok. Then you should calculate your distance by yourself. Below is an example for the metric system
- (NSString *)distanceToMetricStringFromLongValue:(NMAUint64)value {
NSString *distanceText = #"";
if (value < 250) {
NMAUint64 distance = (NMAUint64)round(value / 5.0) * 5;
if (showZeroDistance || distance > 0) {
distanceText = [NSString stringWithFormat:#"%lld m", distance];
}
} else if (value < 500) {
NMAUint64 distance = (NMAUint64)round(value / 10.0) * 10;
if (showZeroDistance || distance > 0) {
distanceText = [NSString stringWithFormat:#"%lld m", distance];
}
} else if (value < 1000) {
NMAUint64 distance = (NMAUint64)round(value / 50.0) * 50;
distanceText = [NSString stringWithFormat:#"%lld m", distance];
} else {
double distance = value / 1000.0;
if (distance >= 10.0) {
distanceText = [NSString stringWithFormat:#"%0.0f km", round(distance)];
} else {
distanceText = [NSString stringWithFormat:#"%0.1f km", distance];
}
}
}
When you create route on map with below method
- (nullable NSProgress *)calculateRouteWithStops:(nonnull NSArray *)stops
routingMode:(nonnull NMARoutingMode *)mode
completionBlock:(nullable NMACalculateResultBlock)completion
Find route length from NMARoute object
NMARoute* route = routeResult.routes[m];
NSLog(#"Route Length is :----- %lu",(unsigned long)route.length);
Official document link
Related
- (IBAction)calciAction:(id)sender {
weightBMI=(([_weightinpounds.text floatValue]) * 4.88)/((([_feet.text floatValue])+ ([_inch.text floatValue]/12)) *(([_feet.text floatValue])+ ([_inch.text floatValue]/12)));
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
formatter.maximumFractionDigits = 2;
formatter.roundingMode = NSNumberFormatterRoundUp;
NSString *numberString = [formatter stringFromNumber:#(weightBMI)];
NSLog(#"YOUR BMI:%#",numberString);
// NSLog(#"Print BMI %f",weightBMI);
// float height = (([_feet.text floatValue]) + ([_inch.text floatValue]));
if (weightBMI>19) {
NSLog(#"low weight");
}
else if ((weightBMI<=19)||(weightBMI>=24))
{
NSLog(#"low normal");
}
else if ((weightBMI<=25)||(weightBMI>=29))
{
NSLog(#"over weight");
}
}
how to write in else if block which is not printed properly
It often helps if you add "plain language" comments to your code. I'm assuming this is what you want to test:
// if weightBMI is LESS THAN 19, weight is low
// if weightBMI is GREATER THAN or EQUAL TO 19, but LESS THAN 25, weight is normal
// if weightBMI is EQUAL TO or GREATER THAN 25, weight is over
if (weightBMI < 19)
{
NSLog(#"low weight");
}
else if (weightBMI < 25)
{
NSLog(#"normal");
}
else
{
NSLog(#"over weight");
}
If you write code in future using swift.Because it's short. :)
switch weightBMI {
case Int.min..<20:
print("low weight")
case 20..<26:
print("low normal")
default:
print("over weight")
}
I want to find total number of close shape.
In image, there are 6 no of close polygons .
I have tried following method
for (NSInteger i = 0; i < [arrLinesInfo count]; i++) {
NSDictionary *dictLineInfo = [arrLinesInfo objectAtIndex:i];
startPoint = CGPointMake([[dictLineInfo valueForKey:#"line_start_point_x"] doubleValue], [[dictLineInfo valueForKey:#"line_start_point_y"] doubleValue]);
endPoint = CGPointMake([[dictLineInfo valueForKey:#"line_end_point_x"] doubleValue], [[dictLineInfo valueForKey:#"line_end_point_y"] doubleValue]);
[self isCircularRoute:startPoint withEndPoint:endPoint];
}
-(void) isCircularRoute:(CGPoint) lineStartPoint withEndPoint:(CGPoint) lineEndPoint
{
NSPredicate *pre= [NSPredicate predicateWithFormat:[NSString stringWithFormat:#"
(self.line_end_point_x == '%f' && self.line_end_point_y == '%f') OR
(self.line_start_point_x == '%f' && self.line_start_point_y == '%f') OR
(self.line_end_point_x == '%f' && self.line_end_point_y == '%f') OR
(self.line_start_point_x == '%f' && self.line_start_point_y == '%f')", lineStartPoint.x,
lineStartPoint.y,
lineStartPoint.x,
lineStartPoint.y,
lineEndPoint.x,
lineEndPoint.y,
lineEndPoint.x,
lineEndPoint.y]];
NSMutableArray *arrSamePointRef = [[arrLinesInfo filteredArrayUsingPredicate:pre] mutableCopy];
arrSamePointRef = [[arrSamePointRef filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:#"
(self.line_start_point_x != '%f' && self.line_start_point_y != '%f') &&
(self.line_end_point_x != '%f' && self.line_end_point_y != '%f')", lineStartPoint.x
, lineStartPoint.y
, lineEndPoint.x
, lineEndPoint.y]]] mutableCopy];//[arrSamePointRef removeObject:dictLineInfo];
if(arrSamePointRef.count > 2){
totalPolygon = totalPolygon + 1;
}
NSLog(#"totalPolygon : ===== %tu", totalPolygon);
for (NSDictionary *dictSingleLine in arrSamePointRef) {
CGPoint newStartPoint = CGPointMake([[dictSingleLine valueForKey:#"line_start_point_x"] doubleValue], [[dictSingleLine valueForKey:#"line_start_point_y"] doubleValue]);
CGPoint newEndPoint = CGPointMake([[dictSingleLine valueForKey:#"line_end_point_x"] doubleValue], [[dictSingleLine valueForKey:#"line_end_point_y"] doubleValue]);
[self isCircularRoute:newStartPoint withEndPoint:newEndPoint];
}
}
This is go in infinite loop.
I have all start point and end point object in array.
array object like below
[
{
"point_start_lbl" : "a",
"point_end_lbl" : "b",
"line_start_point_x" : 200,
"line_start_point_y" : 10,
"line_end_point_x" : 100,
"line_end_point_y" : 10,
}, ...
]
Please help me.
Thanks in advance.
You definitely have a closed polygon if you have an ordered list of edges such that each edge ends on the vertex that the next starts on and no edge is repeated within the list.
I'm unclear about your data structure but I might therefore:
Define an object, Edge that identifies two vertices.
For each vertex, create an array containing every single edge that touches that vertex.
Then, something like, in Swift-ish pseudocode:
var successfulPaths: [Edge] = []
for edge in edges
{
let usedEdges = [edge]
attemptTraversalFrom(edge.vertex1, edge.vertex2, usedEdges, successfulPaths)
attemptTraversalFrom(edge.vertex2, edge.vertex1, usedEdges, successfulPaths)
}
print("There were \(successfulPaths.count) successful paths")
[...]
func attemptTraversalFrom(startingVertex, endingVertex, usedEdges, successfulPaths) {
let vertexEdges = endingVertex.edges
for edge in (edges not in usedEdges) {
let newEndingVertex =
(edge.vertex1 == endingVertex) ? edge.vertex2 : edge.vertex1
if newEndingVertex == startingVertex {
successfulPaths.add(usedEdges)
return
} else {
let newUsedEdges = userEdges.addItem(edge)
attemptTraversalFrom(startingVertex, newEndingVertex, newUsedEdges, successfulPaths)
}
}
// Note: will automatically fall through to here and return
// without adding anything to `successfulPaths` if there are
// no further traversable edges
}
Extemporaneous, etc. A bit like the recursive part of Dijkstra's pathfinding algorithm, except that potential paths are accumulated rather than shorter paths eliminating longer ones prior to complete evaluation.
I am making a game that requires me to use very large numbers. I believe I am able to store very large numbers with NSDecimal. However, when displaying the numbers to users I would like to be able to convert the large number to a succinct string that uses characters to signify the value eg. 100,000 -> 100k 1,000,000 -> 1.00M 4,200,000,000 -> 4.20B and so forth going up to extremely large numbers. Is there any built in method for doing so or would I have to use a bunch of
NSDecimalCompare statements to determine the size of the number and convert?
I am hoping to use objective c for the application.
I know that I can use NSString *string = NSDecimalString(&NSDecimal, _usLocale); to convert to a string could I then do some type of comparison on this string to get the result I'm looking for?
Use this method to convert your number into a smaller format just as you need:
-(NSString*) suffixNumber:(NSNumber*)number
{
if (!number)
return #"";
long long num = [number longLongValue];
int s = ( (num < 0) ? -1 : (num > 0) ? 1 : 0 );
NSString* sign = (s == -1 ? #"-" : #"" );
num = llabs(num);
if (num < 1000)
return [NSString stringWithFormat:#"%#%lld",sign,num];
int exp = (int) (log(num) / 3.f); //log(1000));
NSArray* units = #[#"K",#"M",#"G",#"T",#"P",#"E"];
return [NSString stringWithFormat:#"%#%.1f%#",sign, (num / pow(1000, exp)), [units objectAtIndex:(exp-1)]];
}
Some sample examples:
NSLog(#"%#",[self suffixNumber:#99999]); // 100.0K
NSLog(#"%#",[self suffixNumber:#5109999]); // 5.1M
Source
Solved my issue: Can only be used if you know that your NSDecimal that you are trying to format will only be a whole number without decimals so make sure you round when doing any math on the NSDecimals.
-(NSString *)returnFormattedString:(NSDecimal)nsDecimalToFormat{
NSMutableArray *formatArray = [NSMutableArray arrayWithObjects:#"%.2f",#"%.1f",#"%.0f",nil];
NSMutableArray *suffixes = [NSMutableArray arrayWithObjects:#"k",#"M",#"B",#"T",#"Qa",#"Qi",#"Sx",#"Sp",#"Oc",#"No",#"De",#"Ud",#"Dud",#"Tde",#"Qde",#"Qid",#"Sxd",#"Spd",#"Ocd",#"Nvd",#"Vi",#"Uvi",#"Dvi",#"Tvi", nil];
int dick = [suffixes count];
NSLog(#"count %i",dick);
NSString *string = NSDecimalString(&nsDecimalToFormat, _usLocale);
NSString *formatedString;
NSUInteger characterCount = [string length];
if (characterCount > 3) {
NSString *trimmedString=[string substringToIndex:3];
float a;
a = 100.00/(pow(10, (characterCount - 4)%3));
int remainder = (characterCount-4)%3;
int suffixIndex = (characterCount + 3 - 1)/3 - 2;
NSLog(#"%i",suffixIndex);
if(suffixIndex < [suffixes count]){
NSString *formatSpecifier = [formatArray[remainder] stringByAppendingString:suffixes[suffixIndex]];
formatedString= [NSString stringWithFormat:formatSpecifier, [trimmedString floatValue] / a];
}
else {
formatedString = #"too Big";
}
}
else{
formatedString = string;
}
return formatedString;
}
I have a sorted array of times like so
[0.0, 1.2, 4.3, 5.9, 7.2, 8.0]
While an audio file plays, I want to be able to take the current time and find what the nearest, lower number is in the array.
My approach would be to traverse the array, possible in reverse order as it feels like it should be faster. Is there a better way?
The playback SHOULD be linear, but might be fast-forwarded/rewound, so I would like to come up with a solution that takes that into account, but I'm not really sure how else to approach the problem.
The method you are looking for is -[NSArray indexOfObject:inSortedRange:options:usingComparator:]. It performs a binary search. With the options:NSBinarySearchingInsertionIndex option, if the value isn't found exactly, it returns the index where the object would be inserted, which is the index of the least larger element, or the count of items in the array.
NSTimeInterval currentTime = ...;
NSUInteger index = [times indexOfObject:#(currentTime)
inSortedRange:NSMakeRange(0, times.count)
options:NSBinarySearchingInsertionIndex
usingComparator:^(id object0, id object1) {
NSTimeInterval time0 = [object0 doubleValue];
NSTimeInterval time1 = [object1 doubleValue];
if (time0 < time1) return NSOrderedAscending;
else if (time0 > time1) return NSOrderedDescending;
else return NSOrderedSame;
}];
// If currentTime was not found exactly, then index is the next larger element
// or array count..
if (index == times.count || [times[index] doubleValue] > currentTime) {
--index;
}
The fastest* way to find something in a sorted array is binary search: if there are n items, check the element at index n/2. If that element is greater than what you're looking for, check the element at index n/4; otherwise, if it's less than what you're looking for, check the element at index 3n/4. Continue subdividing in this fashion until you've found what you want, i.e. the position where the current time should be. Then you can pick the preceding element, as that's the closest element that's less than the current time.
However, once you've done that once, you can keep track of where you are in the list. As the user plays through the file, keep checking to see if the time has passed the next element and so on. In other words, remember where you were, and use that when you check again. If the user rewinds, check the preceding elements.
*Arguably, this isn't strictly true -- there are surely faster ways if you can make a good guess as to the probable location of the element in question. But if you don't know anything other than that the element appears somewhere in the array, it's usually the right approach.
I'm not sure if it's the best approach, but I think it'll get the job done (assuming your array is always ascending order).
- (NSNumber *) incrementalClosestLowestNumberForNumber:(NSNumber *)aNumber inArray:(NSArray *)array {
for (int i = 0; i < array.count; i++) {
if ([array[i] floatValue] == [aNumber floatValue]) {
return aNumber;
}
else if ([array[i] floatValue] > [aNumber floatValue]) {
int index = (i > 0) ? i - 1 : 0;
return array[index];
}
}
return #0;
}
Then call it like this:
NSArray * numbArray = #[#0.0, #1.2, #4.3, #5.9, #7.2, #8.0];
NSNumber * closestNumber = [self closestLowestNumberForNumber:#2.4 inArray:numbArray];
NSLog(#"closest number: %#", closestNumber);
I'm not sure if someone else knows a special way that is much faster.
Based on some of the other answers / comments, I came up with this, perhaps one of them can point out if a whole is somewhere.
- (NSNumber *) quartalClosestLowestNumberForNumber:(NSNumber *)compareNumber inArray:(NSArray *)array {
int low = 0;
int high = array.count - 1;
NSNumber * lastNumber;
int currentIndex = 0;
for (currentIndex = low + (high - low) / 2; low <= high; currentIndex = low + (high - low) / 2) {
NSNumber * numb = array[currentIndex];
if (numb.floatValue < compareNumber.floatValue) {
low = currentIndex + 1;
}
else if (numb.floatValue > compareNumber.floatValue) {
high = currentIndex - 1;
}
else if (numb.floatValue == compareNumber.floatValue) {
return numb;
}
lastNumber = numb;
}
if (lastNumber.floatValue > compareNumber.floatValue && currentIndex != 0) {
lastNumber = array[currentIndex - 1];
}
return lastNumber;
}
I'm really bored right now, so I'm trying to test the fastest method. Here's how I did it.
NSMutableArray * numbersArray = [NSMutableArray new];
for (int i = 0; i < 100000; i++) {
float floater = i / 100.0;
[numbersArray addObject: #(floater)];
}
// courtesy #RobMayoff
NSDate * binaryDate = [NSDate date];
NSNumber * closestNumberBinary = [self binaryClosestLowestNumberForNumber:#4.4 inArray:numbersArray];
NSLog(#"Found closest number binary: %# in: %f seconds", closestNumberBinary, -[binaryDate timeIntervalSinceNow]);
// The Quartal Version
NSDate * quartalDate = [NSDate date];
NSNumber * closestNumberQuartal = [self quartalClosestLowestNumberForNumber:#4.4 inArray:numbersArray];
NSLog(#"Found closest number quartal: %# in: %f seconds", closestNumberQuartal, -[quartalDate timeIntervalSinceNow]);
// The incremental version
NSDate * incrementalDate = [NSDate date];
NSNumber * closestNumberIncremental = [self incrementalClosestLowestNumberForNumber:#4.4 inArray:numbersArray];
NSLog(#"Found closest number incremental: %# in: %f seconds", closestNumberIncremental, -[incrementalDate timeIntervalSinceNow]);
And here's the output:
Found closest number binary: 4.4 in: 0.000030 seconds
Found closest number quartal: 4.4 in: 0.000015 seconds
Found closest number incremental: 4.4 in: 0.000092 seconds
And another test case:
Found closest number binary: 751.48 in: 0.000030 seconds
Found closest number quartal: 751.48 in: 0.000016 seconds
Found closest number incremental: 751.48 in: 0.013042 seconds
Below is a method I wrote that takes a random number and makes sure that a sprite does repeat consecutively at the same position. I want to change it so that every new sprite takes a different position of the other two. I am not really getting it right. Please help.
- (float)randomlyChooseXValue {
CGSize s = [[CCDirector sharedDirector] winSize];
int randX = arc4random() % 3;
if (oldRandX != randX) {
if (randX == 0) {
xPos = xPos1*(s.width/480.0);
} else if (randX == 1) {
xPos = xPos2*(s.width/480.0);
} else {
xPos = xPos3*(s.width/480.0);
}
oldRandX = randX;
} else {
[self randomlyChooseXValue];
}
return xPos;
}
If I understand this correctly you need to find 3 random values and the 3rd one should be different then the 1st 2. If this is true you need to store last 2 random values and compare them in the 1st if statement:
- (float)randomlyChooseXValue {
CGSize s = [[CCDirector sharedDirector] winSize];
int randX = arc4random() % 3;
if ((oldRandX1 != randX) && (oldRandX2 != randX)) { //check for 2 values
if (randX == 0) {
xPos = xPos1*(s.width/480.0);
} else if (randX == 1) {
xPos = xPos2*(s.width/480.0);
} else {
xPos = xPos3*(s.width/480.0);
}
oldRandX2 = oldRandX1; //store 1st value to 2nd place
oldRandX1 = randX; //store new value to 1st place
} else {
[self randomlyChooseXValue];
}
return xPos;
}
Since you explained that you are okay with the sequence repeating, then you only need to really make two random choices: the first position, and the direction.
// somewhere, initialize global oldRandX = -1, dir = -1
- (float)randomlyChooseXValue {
CGSize s = [[CCDirector sharedDirector] winSize];
if (oldRandX < 0) {
oldRandX = arc4random() % 3;
dir = arc4random() % 2;
} else if (dir) {
oldRandX = (oldRandX + 1) % 3;
} else {
oldRandX = (oldRandX + 2) % 3;
}
if (randX == 0) {
xPos = xPos1*(s.width/480.0);
} else if (randX == 1) {
xPos = xPos2*(s.width/480.0);
} else {
xPos = xPos3*(s.width/480.0);
}
return xPos;
}
This can generate every possible sequence of the three positions:
0, 1, 2
0, 2, 1
1, 2, 0
1, 0, 2
2, 0, 1
2, 1, 0
and repeat them.
The other answer will achieve the same results, but like your original method, it might take several tries to get it. Your random function can keep choosing the wrong value an unbounded number of times; it becomes a worse problem when there's only one right number to pick.