|
Hello,
I am working on a robots projects and part of this project is a local map space (2D array/matrix).
This map consists of 201 x 201 1cm squares, with the robot sitting in the middle.
From a robots point of view this local map has a index range of -100x -100y to +100x +100y
With the robot sitting at cell 0,0, obviously from a c/c++ point of view.
The array/matrix is addressed from 0x to 200x and 0y to 200y. (0x,0y being array/matrix bottom left)
I have successfully implement a robot rolling road and robot array/matrix rotations.
However, for some reason my brain has gone into gimble lock.
Trying to figure how to find the array/matrix x,y indices for a number of cells at a given angle from the middle of the map (robots position).
The code below produces perfect result for 100 cells at 0,45,90,135,180,225,270,315 degrees but at other angle is fails, can someone help please.
Many thanks in advance imk
#define LOCAL_MAP_NUM_X_CELLS 201
#define LOCAL_MAP_NUM_Y_CELLS 201
#define DEG_TO_RAD 0.0174533
struct LocalMap
{
unsigned char Cell[ LOCAL_MAP_NUM_Y_CELLS ][ LOCAL_MAP_NUM_X_CELLS ];
}; typedef struct LocalMap LocalMap;
int Cell_X;
int Cell_Y;
ComputeLocalMapCellIntexFromCentre( 315 , 100 , &Cell_X , &Cell_Y );
int ComputeLocalMapCellIntexFromCentre( double Angle , int NumberCells , int *pCell_X , int *pCell_Y )
{
double AngleAdjustMent;
double Sin = sin( Angle * DEG_TO_RAD);
double Cos = cos( Angle * DEG_TO_RAD);
double NumCells;
AngleAdjustMent = ( fabs( sin( Angle * DEG_TO_RAD)) + fabs( cos( Angle * DEG_TO_RAD )) );
NumCells = (double)NumberCells;
NumCells = round( (double)NumCells * AngleAdjustMent );
NumberCells = (int)NumCells;
*pCell_X = (int)round( Sin * NumberCells ) + ( LOCAL_MAP_NUM_X_CELLS - 1 ) / 2;
*pCell_Y = (int)round( Cos * NumberCells ) + ( LOCAL_MAP_NUM_Y_CELLS - 1 ) / 2;
return( TRUE );
}
modified 26-Mar-23 13:43pm.
|
|
|
|
|
On the run now so I don't have time for a detailed answer but Bresenham's line algorithm[^] is your friend.
Edit: Here is a detailed solution.
First you have to determine the end point of your line. There might be smarter ways, but a direct way to do it is this:
void find_endpoint (double angle, int* x, int* y)
{
assert (angle >= 0 && angle < 360);
if (angle >= 315 || angle <= 45) {
*x = LOCAL_MAP_NUM_X_CELLS;
*y = (int)round((1 + sin (angle * DEG_TO_RAD)) * LOCAL_MAP_NUM_Y_CELLS / 2);
}
else if (angle <= 135) {
*y = LOCAL_MAP_NUM_Y_CELLS;
*x = (int)round((1 + cos (angle * DEG_TO_RAD)) * LOCAL_MAP_NUM_X_CELLS / 2);
}
else if (angle < 225) {
*x = 0;
*y = (int)round((1 + sin (angle * DEG_TO_RAD)) * LOCAL_MAP_NUM_Y_CELLS / 2);
}
else {
*y = 0;
*x = (int)round((1 + cos (angle * DEG_TO_RAD)) * LOCAL_MAP_NUM_X_CELLS / 2);
}
} Once you have the starting point (100, 100) and the endpoint of your line, it is simply a question of applying the Bresensham algorithm to determine the points on the line:
struct pt {
int x;
int y;
};
void bresenham (int x0, int y0, int x1, int y1, std::vector<pt>& cell)
{
int dx = abs (x1 - x0);
int sx = x0 < x1 ? 1 : -1;
int dy = -abs (y1 - y0);
int sy = y0 < y1 ? 1 : -1;
int error = dx + dy;
while (1)
{
cell.push_back ({ x0, y0 });
if (x0 == x1 && y0 == y1)
break;
int e2 = 2 * error;
if (e2 >= dy)
{
if (x0 == x1)
break;
error = error + dy;
x0 = x0 + sx;
}
if (e2 <= dx)
{
if (y0 == y1)
break;
error = error + dx;
y0 = y0 + sy;
}
}
} Note that this is a direct transcription of the algorithm on the Wikipedia page mentioned above. The number of cells obviously varies so the simplest for me was to keep it in a vector. If you need to have strictly C solution, you will have to manage that yourself.
The caller program looks like this:
int main (int argc, char **argv)
{
int x1, y1;
std::vector<pt> cells;
find_endpoint (30., &x1, &y1);
bresenham (100, 100, x1, y1, cells);
cout << "Angle 30 degrees. End point: "<<x1 << ',' << y1 << endl;
print_cells (cells);
cout << endl;
Mircea
modified 26-Mar-23 19:48pm.
|
|
|
|
|
Normalize the angle to <= 90 (right angle triangle); calculate the opposite and adjacent sides; offset origin x by (int) adjacent, and origin y by (int) opposite.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
Hello this is Gulshan Negi
Well, I want to know about how C and C++ differ in terms of their memory management and performance capabilities, and what strategies can be used to optimize code and improve performance in each language?
I need some suggestions on this.
Thanks
|
|
|
|
|
The difference will depend very much on the implementation of the compiler and associated libraries.
|
|
|
|
|
Gulshan Negi wrote: performance in each language
Performance is based on the following
# Requirements - Most significant.
# Architecture/Design (high level)
# Implementation
# Technology - Least significant.
Your question fits into the last one of those.
If you are very, very good at the first three or your problem (the complete solution) is very, very small then the last one might be the most significant.
|
|
|
|
|
Write a C program to Count the Lines, Words and Characters in a given text
*Write a C program to count the lines, words and characters in a given text.
*At the time of execution, the program should print the following message on the console as:
*Enter lines of text (enter END to complete)
For example, if the user gives the input as:
Enter lines of text (enter END to complete)
CodeTantra developed a Robotic tool
In the year 2016
END
then the program should print the result as:
Character = 51, Words = 9, Lines = 2
Note: Do use the printf() function with a newline character (\n) at the end
|
|
|
|
|
This is your assignment, so you are expected to do the work. If you do not understand the assignment then you need to ask your teacher for guidance.
|
|
|
|
|
Read a line, fgets[^] is your friend.
If the line read is exactly END than your task is complete: report the line, word and character count.
On the other hand, if the line read is not the termination one, then increment the line count, and get the first character (incrementing the character count): if it is a blank then set a flag was_blank = 1; and go on. If it is not a blank then increment the word count and clear the flag: was_blank = 0; .
Go on with the next character (if any): increment the character count and if the character is
|
|
|
|
|
Message Closed
modified 15-May-23 19:06pm.
|
|
|
|
|
There is no simple answer to such a question as the lifetime of a variable will depend on its usage and requirements. You need to analyse your code to decide what is best in each specific case.
|
|
|
|
|
Message Closed
modified 15-May-23 19:06pm.
|
|
|
|
|
Easy peasy
#include <stdargs>
void ProcessCommand (char* command, ...)
{
va_list params;
va_start (params, command);
int narg=args_count(command);
for (i=0; i<narg; i++)
{
QString* pstr = va_arg (params, (QString*));
}
va_end(params);
One of the problems with this code is that you need to know how many arguments to expect and the type of each one. Functions like printf explore format string and figure out from the '%' specifiers. There are countless stories about bugs occurring because they don't match. Sometimes, specially if your arguments are of the same type, you can add a count parameter just before the variable part:
void ProcessCommand (char* command, int count, ...)
Another thought: if you know that all parameters are of the same type, why not pass an array. Something like this:
void ProcessCommand (char *command, std::vector<QString*> verify)
{
for (auto& pstr : verify)
{
}
}
Mircea
|
|
|
|
|
This article can probably explain it a lot better than I can. In particular I did not know that the argument before the ellipses must not be something that is eligible for default parameter promotion (e.g a float, which gets promoted to double).
Modern C++ and Variadic Functions: How to Shoot Yourself in the Foot and How to Avoid It
You should take note of the discussion of how the variadic function determines how many arguments it has.
I also have an idea that stdargs may not be the preferred way to write a variadic function in C++ any longer. There's a tickle in the back of my brain that perhaps variadic templates are a better way to go. If you're interested in that, check out Jason Turners C++ weekly episodes on You Tube: C++ Weekly - Ep 6 Intro To Variadic Templates - YouTube
Keep Calm and Carry On
|
|
|
|
|
It dpends om what type the extra parameters are. If they are all the same (e.g. all ints, chars etc.) then you are better using an array or a C++ container. But if you are passing a variable number of varying types then you need some way of identifying which type each parameter is. In the C library printf/scanf functions this is done with the format string, where each control item in the string tells the function what type to expect for the corresponding variable.
|
|
|
|
|
Besides the other answers you might want to ask how many of these would be reasonable in the next 5 years of using this method.
So if you start with 2 now and there are 4 in 5 years ok.
But if you start with 2 now and in three months there are 20 then that is a problem. In that case a collection of some sort is better.
|
|
|
|
|
" in three months there are 20"
Nah, they're on to the next project.... who cares about code maintenance?
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
|
It still requires enforcing correct usage which can only occur via discipline and/or careful code reviews.
And if you are doing that then you shouldn't have a problem in the first place. More careful designs can also reduce the problem.
|
|
|
|
|
My thoughts exactly. Seems more trouble than it's worth.
Mircea
|
|
|
|
|
Message Closed
modified 15-May-23 19:06pm.
|
|
|
|
|
It's not wrong. Empty statement is a valid C/C++ statement. You can try:
;;;;
Also, a very popular beginner mistake is to add a spurious semicolon at the end of a while and wonder why the while "body" is not repeated:
while (i>0); {
}
Mircea
modified 1-Mar-23 14:07pm.
|
|
|
|
|
|
Aren’t we all beginners constantly trying to learn new things? Do you think I saw that error in a book?
Mircea
|
|
|
|
|
To add to what Mircea has said, you may even include empty blocks e.g.
int main()
{
{}
std::cout << "Hello World!\n";
{}
}
compiles without complaint.
While that seems rather silly, source code like that might be generated when a pre-processor #define is expanded or perhaps if you have some sort of code generator as part of the build process. e.g. something like Oracle Pro*C, or Postgresql ecpg.
Keep Calm and Carry On
|
|
|
|