how to return angle from hypotenuse with legs as parameters - angle

the function returns the angle of the resulting hypotenuse from the calculus using the opposite leg (y) and the adjacent leg (x)
i don't understand this code, can anyone help me?
(the function in the context of << and >> symbols)
int atan2_cordic(Uint16 y, Uint16 x)
{
Uint16 angle;
int t;
Uint8 b;
// Singular cases
if (y==0) return 0; if (x==0) return 90; // 0º and 90º
// Rotate until angle is below atan(1/2). Angle in 1/2º units
angle=0;
t=y-x;
if(t>=0)
{
angle=90;
x+=y;
y=t;
}
t=(y<<1)-x;
if(t>=0)
{
angle+=53;
x<<=1; x+=y;
y=t;
}
y*=106;
y/=x;
y++; // (x/y)*106 + 1
angle+=y; // Add previous rotation
b=angle&0x01;
angle>>=1;
if (b) angle++; // divide by 2 with rounding
return angle;
}

Related

How do I call operator function to add two objects? [duplicate]

This question already has an answer here:
Overloaded Addition assignment operator in C++ for two /more than two objects?
(1 answer)
Closed 5 years ago.
Trying to develop operator == to compare two balls where two balls are considered equal if they have the same radius and operator > to compare two balls. To see if one ball has a bigger radius than another one, for let's say ball x is > than another ball y. += to add the volume of the right-side-operand to the volume of the left-side-operand. It is like to melt two metal balls to make one metal ball. The new ball's radius is cube root of (r1^3 + r2^3). Wish to use pow() function to calculate the cube value and cube root value. operator + to add the two balls together and return a new ball. The size of the new ball is the sum of the size of the two operands connected by the +.
In the main() function, couldn't add ball m(10) with ball n(20) to create another ball d, like d = m+n.
int main()
{
//use ball
ball x; float re;
//radius of ball y is set to 10
ball y(10);
//asks for radius of x?
cout << "Enter radius for ball x: ";
cin >> re;
//sets the radius of x
x.set_radius(re);
ball m(10);
ball n(20);
ball d;
d = m + n;
//cout << "The radius of ball d is " << m.;
system("pause");
return 0;
}
//ball.h
{
class ball
{
public:
//sets the intial raduis to 0
ball() {
radius = 0;
}
ball(float radii) {
radius = radii;
}
float get_radius() {
return radius;
}
void set_radius(float redly) {
radius = redly;
}
bool operator == (ball x) {
if (radius == x.radius)
return true;
else
return false;
}
bool operator > (ball x) {
if (radius > x.radius)
return true;
else
return false;
}
bool operator += (ball x) {
radius += x.radius;
}
ball operator + (ball a, ball b) {
ball d;
d += a;
d += b;
return d;
}
private:
float radius;
};
}
#endif
If you are only looking for (x_volume/ y_volume)% and (x_surfacearea/y_surfacearea)%
I suggest doing :
float vol_over_y() {
float v;
v = ((radius * radius * radius)/(10*10*10));
return v;
}
float sa_over_y() {
float a;
a = (radius * radius /(10*10));
return a;
}
because other constants like (4.0/3.0)* 3.14 in volume and 3.14 in surface area cancel out.
If in case y changes,
float vol_over_y(float y_rad) {
float v;
v = ((radius * radius * radius)/(y_rad*y_rad*y_rad));
return v;
}
float sa_over_y(float y_rad) {
float a;
a = (radius * radius /(y_rad*y_rad));
return a;
}
You thought too much. It is simply a little tweak in your main logic:
ball x;
ball y(10);
// your code to construct x
cout << "The volume of x is " << ( x.volume() / y.volume() )<< "% of the volume of y."<< endl;
// similar for surface area, try it out yourself
If in case you really need to do it in a method(which is quite ridiculous imho), you should just pass the other ball in and calculate:
float volume_ratio_to(const ball& base) {
return volume() / base.volume();
}
And your main logic become
cout << "The volume of x is " << x.volume_ratio_to(y) << "% of the volume of y."<< endl;
Edited for your updated question:
The reason why + operator does not work for you is because you didn't overloaded the operator right.
If you want it to be member of ball, the + operator should only takes one argument.
i.e. looks like:
class ball {
//....
ball operator + (ball another);
}
Or, don't make it member of ball:
// outside ball class
ball operator + (ball a, ball b) {....}
Refer to Overloaded Addition assignment operator in C++ for two /more than two objects? for more detailed description on how to overload addition operator.
There are quite a lot of other problems in your code too
You should have passed balls to methods by reference instead of by value
You should have considered adding const in various places
You += logic is totally wrong. Pay attention to what you quoted:
+= to add the volume of the right-side-operand to the volume of the
left-side-operand. It is like to melt two metal balls to make one
metal ball. The new ball's radius is cube root of (r1^3 + r2^3)
//This helps
int main()
{
//use ball
ball x; float re;
ball y(10);
cout << "Enter radius for ball x: " << endl;
cin >> re;
x.setl(re);
cout << "The volume of x is " << (x.volume()/y.volume())*100 << "%
of the volume of y."<< endl;
cout << "The surfacearea of x box is " <<
(x.surface_area()/y.surface_area())*100 << "% of
the surfacearea of y." << endl;
system("pause");
return 0;
}
//ball.h
#pragma once
#ifndef Ball
#define Ball
namespace bsize
{
class ball
{
public:
ball(){
radius = 0;
}
ball(float radii) {
radius = radii;
}
float volume() {
float v;
v = ((4.0/3.0)* 3.14 * (radius * radius * radius));
return v;
}
float surface_area() {
float a;
a = (4 * 3.14 * radius * radius);
return a;
}
float get_radius(){
return radius;
}
void set_radius(float redly) {
radius = redly;
}
private:
float radius;
};
}
#endif

i keep getting list iterator not dereferencable, what am i doing wrong?

I'm having trouble with with this project of mine. i want it to draw out an octagon, the code i used worked perfectly fine for other shapes like rhombus and triangle.
the octagon.cpp file http://pastebin.com/iVfdkKEB
the header file http://pastebin.com/a50UQi5F
the main part which runs it all http://pastebin.com/quepi6az
#include "shape.h"
class Octagon : public Shape
{
int radius;
void plotVertices();
public:
Octagon(Vertex point, int radius = 10);
int area();
int perimeter();
};
#include "octagon.h"
Octagon::Octagon(Vertex point, int radius) : Shape(point)
{
// constructs a Octagon of radius around a point in 2D space
if ((radius>centroid.getX() / 2) || (radius>centroid.getX() / 2))
{
cout << "Object must fit on screen." << endl;
system("pause");
exit(0);
this->radius = radius;
plotVertices();
}
// place your code here and add comments that describe your understanding of what is happening
}
void Octagon::plotVertices()
{
int x, y, _x, _y; // declare and intiliase variables for x and y co-ordinates
double radians;
x = centroid.getX(); // places first point A at the centroid
y = centroid.getY() + radius;
vertices.push_back(Vertex(x, y));
x = vertices.back().getX() - centroid.getX();
y = vertices.back().getY() - centroid.getY();
for (int i = 45; i < 360; i += 45) // for loop to draw the shape itself by creating the points.
// i = size of interior angle.
{
radians = i * PI / 180;
_x = round(x * cos(radians) - y * sin(radians));
_y = round(y* cos(radians) + x * sin(radians));
_x = _x + centroid.getX();
_y = _y + centroid.getY();
vertices.push_back(Vertex(_x, _y));
}
}
#pragma once
#include "vertex.h"
#include "shape.h"
#include "octagon.h"
#include "console.h"
#include <iostream>
#include <list>
#include <cmath>
#include <iostream>
using namespace std;
int main()
{
list<Shape*> shapes;
int x = 20, y = 60;
shapes.push_back(new Octagon(Vertex(20, 60), 8));
list<Shape*>::iterator itr = shapes.begin();
while(itr!=shapes.end())
{
(*itr)->drawShape();
system("pause");
(*itr)->outputStatistics();
// output shape statistics
(*itr)->scale(2.0);
(*itr)->drawShape();
// scale shape (double it)
// draw shape
(*itr)->rotate(20);
(*itr)->drawShape();
// rotate shape by 20 degrees
// draw shape
itr++;
}
Console::gotoXY(0,0);
system("pause");
return 0;
}
and the draw shape function
void Shape::drawShape()
{
// plots each vertex and draws a line between them using Bresenham's algorithm
// you can adjust your console font and dimensions if you want to increase the resolution of your shapes
list<Vertex>::iterator current = vertices.begin();
list<Vertex>::iterator previous = vertices.begin();
while (current != vertices.end())
{
Console::gotoXY((*current).getX(), (*current).getY());
cout << "*";
if (current != vertices.begin())
drawLine((*current).getX(), (*current).getY(), (*previous).getX(), (*previous).getY());
previous = current;
current++;
}
drawLine(vertices.back().getX(), vertices.back().getY(), vertices.front().getX(), vertices.front().getY());
}
I'm far from sure, but I think that the problem can be in the last line of void Shape::drawShape()
drawLine(vertices.back().getX(), vertices.back().getY(), vertices.front().getX(), vertices.front().getY());
where isn't a check to see if vertices is empty. In that case, vertices.back() and vertices.front() are undefined (both equal to vertices.end()?) and dereferencing they, to call getX() and getY(), can cause your problem.
It's possible an empty vertices? I don't know because I don't see all code but I see that there is an exit(0) in the if body of the Octagon constructor.
It's plotVertices() that populate vertices? In this case, the exit(0) say us that vertices is empty and that the last drawline() in Shape::drawshape can cause the trouble.
The solution (a solution) is obvious and simple: check if vertices is empty
if ( false == vertices.empty() )
drawLine(vertices.back().getX(), vertices.back().getY(), vertices.front().getX(), vertices.front().getY());

program is not printing at right points although the coordinates are correct

I want to build a program that stimulate the behavior of a projectile motion. I have checked the coordinates (x, y) which are correct but the compiler is not printing at right coordinates resulting in an inverted projectile motion(swing like motion)
the file "myconsole.h"is working correctly I have checked it separately.
here is my code:
#include <iostream>
#include <cmath>
#include <windows.h>
#include "myconsole.h"
using namespace std;
int coordinate(int theta, float v, float g, float initialheight, float x) //function to calculate y coordinate. it accepts x and produces y
{
float y = ((initialheight + (x * tan(theta))) - (( g * (x * x))/(2 * (powf((v * cos(theta)), 2)))));//formula
return y;
}
int main()
{
float initialheight = 0;
int y = 0;
int x = 0;
float v = 0;
int theta =0;
float g = 9.81;
cout<<"Enter the following Information"<<endl;
cout<<"Angle (theta) = ";
cin>>theta;
cout<<"Initial Velocity (V) = ";
cin>>v;
cout<<"Initial height = ";
cin>>initialheight;
float sq = 2*g*initialheight;//just for simplification
float sqroot = powf(v * (sin(theta)), 2);//just for simplification
float d = ((v * (cos(theta))/g)*((v * (sin(theta))+ sqrt(sqroot + sq))));
/*equation to calculate total distance covered
by the projectile. I started x from 0 and add 1 to it till it reaches d.for every value of x we get the
corisponding value of y from function coordinate.*/
ClearScreen();
while(x <= d)//loop to increment x
{
y = coordinate(theta, v, g, initialheight, x);
PlaceCursor(x, y); //using function from console.h and placing the cursor at (x, y) position
cout<<"*";
/*although the coordinates are stimulating the correct behavior of projectile but "* " are printing
an inverted projectile*/
x++;
}
system("pause");
return 0 ;
}
I believe the coordinate system for a console window starts at 0,0 in the top left and y increases down the window. Your code is correct, the graph itself is inverted because that's how the coords work.
I changed your code like this to get the desired result:
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo (hStdout, &csbiInfo);
int winheight = csbiInfo.dwSize.Y ;
system("cls");
while(x <= d)//loop to increment x
{
y = coordinate(theta, v, g, initialheight, x);
COORD pos;
pos.X = x;
pos.Y = winheight -y;
SetConsoleCursorPosition(hStdout, pos);
cout<<"*";
Without coding it up, this should fix it, change the value of gravity to a negative value in your equation as it's pulling in the opposite direction to your projectile.

I need to understand the top function, more specific then i already know. The bottom function is pretty much self-explanatory

bool isOnPerimeter - function that I need help with.
bool isOnPerimeter(int row, int column, int radius)
{
double dRow=static_cast<double>(row);
double dColumn=static_cast<double>(column);
double dRadius=static_cast<double>(radius);
if (pow(dRow,2.0)+pow(dColumn,2.0)<=pow(dRadius,2.0) &&
pow(dRow,2.0)+pow(abs(dColumn)+1,2.0) > pow(dRadius,2.0))
return true;
else
return false;
}
void drawCircle(int radius)
{
for (int row = -radius;row <= radius;++row)
{
for (int column = -radius;column <= radius;++column)
{
if (isOnPerimeter(row,column,radius))
cout << "*";
else
cout << " ";
cout << endl;
}
}
}
the function looks like it's drawing a circle inside the square define by coordinates (-radius,-radius), (radius,radius).
How it does that: consider the trigonometric circle, you know that sin^2 + cos^2 = R^2. Since sin and cos are the projections of R on oy and ox axes, all the points inside the circle have the property that sin^2 + cos^2 < R^2 and all the points outside the circle have the property sin^2 + cos^2 > R^2
In your example you row, col are the equivalent of sin, cos. So you determine the edge of the circle as being all the points for which
sin^2 + cos^2 <= R^2 && sin^2 + (cos+1)^2 > R^2
Hope this helps

Implementing Table-Lookup-Based Trig Functions

For a videogame I'm implementing in my spare time, I've tried implementing my own versions of sinf(), cosf(), and atan2f(), using lookup tables. The intent is to have implementations that are faster, although with less accuracy.
My initial implementation is below. The functions work, and return good approximate values. The only problem is that they are slower than calling the standard sinf(), cosf(), and atan2f() functions.
So, what am I doing wrong?
// Geometry.h includes definitions of PI, TWO_PI, etc., as
// well as the prototypes for the public functions
#include "Geometry.h"
namespace {
// Number of entries in the sin/cos lookup table
const int SinTableCount = 512;
// Angle covered by each table entry
const float SinTableDelta = TWO_PI / (float)SinTableCount;
// Lookup table for Sin() results
float SinTable[SinTableCount];
// This object initializes the contents of the SinTable array exactly once
class SinTableInitializer {
public:
SinTableInitializer() {
for (int i = 0; i < SinTableCount; ++i) {
SinTable[i] = sinf((float)i * SinTableDelta);
}
}
};
static SinTableInitializer sinTableInitializer;
// Number of entries in the atan lookup table
const int AtanTableCount = 512;
// Interval covered by each Atan table entry
const float AtanTableDelta = 1.0f / (float)AtanTableCount;
// Lookup table for Atan() results
float AtanTable[AtanTableCount];
// This object initializes the contents of the AtanTable array exactly once
class AtanTableInitializer {
public:
AtanTableInitializer() {
for (int i = 0; i < AtanTableCount; ++i) {
AtanTable[i] = atanf((float)i * AtanTableDelta);
}
}
};
static AtanTableInitializer atanTableInitializer;
// Lookup result in table.
// Preconditions: y > 0, x > 0, y < x
static float AtanLookup2(float y, float x) {
assert(y > 0.0f);
assert(x > 0.0f);
assert(y < x);
const float ratio = y / x;
const int index = (int)(ratio / AtanTableDelta);
return AtanTable[index];
}
}
float Sin(float angle) {
// If angle is negative, reflect around X-axis and negate result
bool mustNegateResult = false;
if (angle < 0.0f) {
mustNegateResult = true;
angle = -angle;
}
// Normalize angle so that it is in the interval (0.0, PI)
while (angle >= TWO_PI) {
angle -= TWO_PI;
}
const int index = (int)(angle / SinTableDelta);
const float result = SinTable[index];
return mustNegateResult? (-result) : result;
}
float Cos(float angle) {
return Sin(angle + PI_2);
}
float Atan2(float y, float x) {
// Handle x == 0 or x == -0
// (See atan2(3) for specification of sign-bit handling.)
if (x == 0.0f) {
if (y > 0.0f) {
return PI_2;
}
else if (y < 0.0f) {
return -PI_2;
}
else if (signbit(x)) {
return signbit(y)? -PI : PI;
}
else {
return signbit(y)? -0.0f : 0.0f;
}
}
// Handle y == 0, x != 0
if (y == 0.0f) {
return (x > 0.0f)? 0.0f : PI;
}
// Handle y == x
if (y == x) {
return (x > 0.0f)? PI_4 : -(3.0f * PI_4);
}
// Handle y == -x
if (y == -x) {
return (x > 0.0f)? -PI_4 : (3.0f * PI_4);
}
// For other cases, determine quadrant and do appropriate lookup and calculation
bool right = (x > 0.0f);
bool top = (y > 0.0f);
if (right && top) {
// First quadrant
if (y < x) {
return AtanLookup2(y, x);
}
else {
return PI_2 - AtanLookup2(x, y);
}
}
else if (!right && top) {
// Second quadrant
const float posx = fabsf(x);
if (y < posx) {
return PI - AtanLookup2(y, posx);
}
else {
return PI_2 + AtanLookup2(posx, y);
}
}
else if (!right && !top) {
// Third quadrant
const float posx = fabsf(x);
const float posy = fabsf(y);
if (posy < posx) {
return -PI + AtanLookup2(posy, posx);
}
else {
return -PI_2 - AtanLookup2(posx, posy);
}
}
else { // right && !top
// Fourth quadrant
const float posy = fabsf(y);
if (posy < x) {
return -AtanLookup2(posy, x);
}
else {
return -PI_2 + AtanLookup2(x, posy);
}
}
return 0.0f;
}
"Premature optimization is the root of all evil" - Donald Knuth
Nowadays compilers provide very efficient intrinsics for trigonometric functions that get the best from modern processors (SSE etc.), which explains why you can hardly beat the built-in functions. Don't lose too much time on these parts and instead concentrate on the real bottlenecks that you can spot with a profiler.
Remember you have a co-processor ... you would have seen an increase in speed if it were 1993 ... however today you will struggle to beat native intrinsics.
Try viewing the disassebly to sinf.
Someone has already benchmarked this, and it looks as though the Trig.Math functions are already optimized, and will be faster than any lookup table you can come up with:
http://www.tommti-systems.de/go.html?http://www.tommti-systems.de/main-Dateien/reviews/languages/benchmarks.html
(They didn't use anchors on the page so you have to scroll about 1/3 of the way down)
I'm worried by this place:
// Normalize angle so that it is in the interval (0.0, PI)
while (angle >= TWO_PI) {
angle -= TWO_PI;
}
But you can:
Add time-meters to all functions, write special performance tests, run performance tests, print report of time test.. I think you will know answer after this tests.
Also you could use some profiling tools such as AQTime.
The built-in functions are very well optimized already, so it's going to be REALLY tough to beat them. Personally, I'd look elsewhere for places to gain performance.
That said, one optimization I can see in your code:
// Normalize angle so that it is in the interval (0.0, PI)
while (angle >= TWO_PI) {
angle -= TWO_PI;
}
Could be replaced with:
angle = fmod(angle, TWO_PI);