CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Jul 2018
    Posts
    3

    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].

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    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)

  3. #3
    Join Date
    Jul 2018
    Posts
    3

    Re: Lookup table with angles

    C++ (Visual Studio 2013).

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    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

    Code:
    -15.4 -9.3
    27.8 34
    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)

  5. #5
    Join Date
    Jul 2018
    Posts
    3

    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.

  6. #6
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Lookup table with angles

    For angle = 80 I get

    Code:
    -9.3 0
    34 40.1
    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

    Code:
    34 40.1
    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)

  7. #7
    Join Date
    Feb 2017
    Posts
    677

    Re: Lookup table with angles

    Quote Originally Posted by Cripi View Post
    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.

  8. #8
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    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
  •  





Click Here to Expand Forum to Full Width

Featured