-
July 6th, 2018, 06:53 AM
#1
Lookup table with angles
I have a table with 2 columns; here’s two typical examples:
Code:
TABLE 1 TABLE 2
X Y X Y
-46.3 16.0 -50.3 71.2
-40.1 -28.1 -43.6 117.7
-34.0 -154.0 -36.9 165.7
-27.8 -171.8 -30.2 176.9
-21.6 178.0 -23.5 -179.2
-15.4 166.2 -16.8 -173.3
-9.3 120.1 -10.1 -149.3
-3.1 -2.0 -3.4 -86.2
3.1 -28.6 3.4 -67.0
9.3 -80.7 10.1 -72.8
15.4 -147.7 16.8 -93.5
21.6 -175.5 23.5 -151.7
27.8 162.6 30.2 112.9
34.0 120.2 36.9 80.4
40.1 49.4 43.6 67.7
46.3 15.4 50.3 71.4
In the table 1, the Y decreases, while in the table 2 the Y increases. But notice the ambiguity in the table 1 for Y= 150 and in the table 2 for Y= 70.
I generate one table at runtime (I plan to use from 20 to 50 rows), the column Y is an angle (I use radians from –pi to pi and double precision number, but here I used degrees for the sake of simplicity).
The program generates an angle from –pi to pi and I need to find the two X’s that bracket the angle. For example, if the angle is 150, for the table 1 the function should find [-15.4, -9.3] and [27.8, 34.0].
-
July 6th, 2018, 07:12 AM
#2
Re: Lookup table with angles
What language are you using?
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
July 6th, 2018, 07:19 AM
#3
Re: Lookup table with angles
C++ (Visual Studio 2013).
-
July 6th, 2018, 11:11 AM
#4
Re: Lookup table with angles
One simple way of doing this is as below
Code:
#include <map>
#include <vector>
#include <utility>
#include <iostream>
using namespace std;
int main()
{
const vector<pair<double, double>> tb1 {{16, -46.3}, {-28.1, -40.1}, {-154.0, -34}, {-171.8, -27.8}, {178, -21.6}, {166.2, -15.4}, {120.1, -9.3},
{-2, -3.1}, {-28.6, 3.1}, {-80.7, 9.3}, {-147.7, 15.4}, {-175.5, 21.6}, {162.6, 27.8}, {120.2, 34}, {49.4, 40.1}, {15.4, 46.3}};
const double ang = 150.0; // Angle to find
bool gotneg = false;
map<double, double> mdd;
for (auto nit = tb1.begin(), nlast = prev(tb1.end()); nit != tb1.end(); ++nit)
if (((nit->first < 0) == gotneg) && (nit != nlast))
mdd[nit->first] = nit->second;
else {
const auto lb = mdd.lower_bound(ang);
const auto ub = mdd.upper_bound(ang);
if ((lb != mdd.end()) && (ub != mdd.end()) && (ub != mdd.begin()))
cout << lb->second << " " << prev(ub)->second << endl;
gotneg = !gotneg;
mdd.clear();
mdd[nit->first] = nit->second;
}
}
tb1 is a vector containing the values for table 1 and ang is the angle to find.
This makes a map of the entries from tb1 where the sign of the key is the same. When the sign changes or the end of the vector is reached, it uses lower_bound() and upper_bound() on the map to obtain the required values.
Running the above program gives output of
as required.
Note that limited testing has been done - so some edge cases may need looking at more closely.
PS As VS2013 is now 5 years old I don't have it installed any more so can't say whether this code will compile or not. The current version of VS is VS2017 which supports the current c++17 standard. There have been many changes to c++ since VS2013 and I suggest you really ought to consider upgrading to VS2017.
Last edited by 2kaud; July 6th, 2018 at 01:32 PM.
Reason: Code change as per post #6
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
July 6th, 2018, 11:34 AM
#5
Re: Lookup table with angles
For ang= 80, I get the error: "Expression: map/set iterator not dereferencable". Unfortunately I'm not familiar with those structures and I don't know how to debug the program.
EDIT: now I read your PS, but an explanation of what your program does would help a lot, that way I can code your explanation in a more familiar way for me.
Last edited by Cripi; July 6th, 2018 at 11:42 AM.
-
July 6th, 2018, 12:48 PM
#6
Re: Lookup table with angles
For angle = 80 I get
The first one is incorrect. OK. I said I hadn't tested edge conditions carefully. Try changing this line
Code:
if ((lb != mdd.end()) && (ub != mdd.end()))
to
Code:
if ((lb != mdd.end()) && (ub != mdd.end()) && (ub != mdd.begin()))
This now gives
an explanation of what your program does would help a lot
I did. If you haven't used lower_bound() or upper_bound() before see
http://www.cplusplus.com/reference/map/map/lower_bound/
http://www.cplusplus.com/reference/map/map/upper_bound/
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
July 7th, 2018, 02:41 AM
#7
Re: Lookup table with angles
Originally Posted by Cripi
But notice the ambiguity
find the two X’s that bracket the angle.
The first step is always to clearly define the preconditions. What do you mean by "bracket the angle". Is it a pair of neighbor angles in the Y list of which one is smaller and one is bigger than the target angle? And what do you mean by "ambiguity"? Is it when more than one pair of neighbor angles fit the criterion of "bracket the angle"?
If the above is what you require then the algorithm is quite straightforward. You walk through the angles one by one. If the current angle and the next angle are such that one is smaller and one is bigger than the target angle then you have a hit. After a hit you continue since there may be more hits to come.
Last edited by wolle; July 8th, 2018 at 06:12 AM.
-
July 7th, 2018, 03:39 AM
#8
Re: Lookup table with angles
Yes, well, I think I 'over-egged the pudding'. In my defence, too much work, juggling too many balls, too much sun, England playing today.... Wolle's solution is of course far simpler. Along the lines of
Code:
#include <vector>
#include <iostream>
using namespace std;
int main()
{
const vector<pair<double, double>> tb1 {{16, -46.3}, {-28.1, -40.1}, {-154.0, -34}, {-171.8, -27.8}, {178, -21.6}, {166.2, -15.4}, {120.1, -9.3},
{-2, -3.1}, {-28.6, 3.1}, {-80.7, 9.3}, {-147.7, 15.4}, {-175.5, 21.6}, {162.6, 27.8}, {120.2, 34}, {49.4, 40.1}, {15.4, 46.3}};
const double ang = 80.0; // Angle to find
for (auto nit = tb1.begin(), nlast = prev(tb1.end()); nit != nlast; ++nit) {
const auto& f = nit->first;
const auto& s = next(nit)->first;
if (((f < 0 && s < 0) || (f > 0 && s > 0)) && (s < ang) && (f > ang))
cout << nit->second << " " << next(nit)->second << endl;
}
}
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|