C++ segment line intersection - c++

i would like to ask where is the problem?
I got an error: invalid type argument of ‘unary *’
I am new in c++ programming, i use java style.
Pointer and dereference is a big problem for me.
My application got input values and save as point object, after this i should find intersection of 2 lines.
I thought to return a Point object in which i will compute x and y value.
.h file
class Point {
public:
double x_val, y_val;
Point(double, double);
double x();
double y();
double dist(Point other);
Point add(Point b);
Point sub(Point b);
void move(double a, double b);
};
class Triungle {
public:
Triungle(std::string);
void compute_length();
void lines_intersect(Point a, Point b, Point c, Point d, Point *intersection);
Point a, b, c;
};
.cpp file
Point::Point(double x = 0.0, double y = 0.0) {
x_val = x;
y_val = y;
}
double Point::x() {
return x_val;
}
double Point::y() {
return y_val;
}
double Point::dist(Point other) {
double xd = this->x() - other.x();
double yd = this->y() - other.y();
return sqrt(xd * xd + yd * yd);
}
Point Point::add(Point b) {
return Point(x_val + b.x_val, y_val + b.y_val);
}
Point Point::sub(Point b) {
return Point(x_val - b.x_val, y_val - b.y_val);
}
void Point::move(double a, double b) {
x_val += a;
y_val += b;
}
void Triungle::lines_intersect(Point a, Point b, Point c, Point d, Point *intersection) {
double x, y;
double A1 = b.y_val - a.y_val;
double B1 = b.x_val - a.x_val;
double C1 = a.y_val - (A1 / B1) * a.x_val;
double A2 = d.y_val - c.y_val;
double B2 = d.x_val - c.x_val;
double C2 = c.y_val - (A2 / B2) * c.x_val;
double det = (A1 / B1) - (A2 / B2);
if (det == 0) {
// lines are paralel
} else {
x = (C2 - C1) / det;
y = (A1 * C2 - A2 * C1) / det;
}
*intersection->x_val = x; // here i got error
*intersection->y_val = y; // here i got error
}
Triungle::Triungle(std::string s) {
cout << "enter first point of " << s << " triangle: ";
cin >> a.x_val;
cin >> a.y_val;
if (!(cin)) {
cout << "input error." << endl;
exit(1);
}
cin.clear();
cout << "enter second point of " << s << " triangle: ";
cin >> b.x_val;
cin >> b.y_val;
if (!(cin)) {
cout << "input error." << endl;
exit(1);
}
cin.clear();
cout << "enter 3 point of " << s << " triangle: ";
cin >> c.x_val;
cin >> c.y_val;
if (!cin) {
cout << "input error." << endl;
exit(1);
}
cin.clear();
}
and i call function in this way
int main(int argc, char** argv) {
Triungle a("first");
Triungle b("second");
Point p;
a.lines_intersect(a.a, a.b, a.c, a.a, &p);
}

intersection->member
will dereference a pointer intersection. This is the same as
(*intersection).member
you don't need to dereference it twice.

What you do in your code
*intersection->x_val = x;
is an equivalent to
(*(intersection->x_val)) = x;
because operator of selection through pointer -> has higher precedence than dereference operator *, and the latter has higher precedence than assignment operator =.
So first your select member double x_val of class Point.
Second you try to apply unary dereference operator * to the result. And because x_val is double, not a pointer, which is expected by dereference operator, compiler reports an error.
Thus, dereference operator is excessive here and it's enough to do the following
intersection->x_val = x;

Assuming that the error you get is a compilation error on the two lines:
*intersection->x_val = x; // here i got error
*intersection->y_val = y; // here i got error
The problem is that you are de-referencing a pointer, and then using the derefencing operator -> on it.
Instead, you should either do:
intersection->x_val = x;
intersection->y_val = y; // leave it as a pointer
or
*intersection.x_val = x;
*intersection.y_val = y; // use it as an object

Related

How can I Modify this code to take user input?

How to modify this code so the program can take user input instead of predefined input:
the code is to check if two line are intersecting or not in this code the values of the points are given but i want the program to ask the values at the run time.
struct point
{
lli x, y;
};
int orientation(point p1, point p2, point p3)
{
int val = (p2.y - p1.y) * (p3.x - p2.x) -
(p2.x -p1.x) * (p3.y -p2.y);
if (val == 0) return 0;
return (val > 0)? 1: 2;
}
bool validprojection(int a, int b, int c, int d)
{
if (a > b)
swap(a,b);
if (c > d)
swap(c, d);
return max(a, c) <= min(b, d);
}
bool doIntersect(point a, point b, point c, point d)
{
int o1 = orientation(a, b, c);
int o2 = orientation(a, b, d);
int o3 = orientation(c, d, a);
int o4 = orientation(c, d, b);
if(o1 != o2 && o3 != o4)
return true;
if (o1 == 0 && o4 == 0)
{
if(validprojection(a.x, b.x, c.x, d.x) && validprojection(a.y, b.y, c.y, d.y))
return true;
}
return false;
}
predefined input:
how can i modify this part so it will ask user to input the values of point
int main()
{
cout<<"To find the intersection point of two line segment";
point p1 = {1, 1}, p2 = {10, 1}, p3 = {1, 2}, p4 = {10, 2};
doIntersect(p1, p2, p3, p4)? cout << "yes\n": cout<< "No\n";
p1 = {10, 0}, p2 = {0, 10}, p3 = {0, 0}, p4 = {10, 10};
doIntersect(p1, p2, p3, p4)? cout << "yes\n": cout<< "No\n";
return 0;
Code
#include <iostream>
#include <string>
#include <sstream>
std::ostream &operator<<(std::ostream &os, Point &p) {
return os << p.x << ',' << p.y;
}
int main() {
Point points[2][2];
std::string line;
while (true) {
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
std::cout << "Line " << i + 1<< ", Point " << j + 1 << " (x,y): "; // Prints: "Line i, Point j (x,y): "
std::getline(std::cin, line);
if (line.size() == 0) {
goto end;
}
std::stringstream ss(line);
ss >> points[i][j].x;
ss.ignore(1, ',');
ss >> points[i][j].y;
line.clear();
}
}
bool intersect = doIntersect(points[0][0], points[0][1], points[1][0], points[1][1]);
std::cout << "The lines 1 [(" << points[0][0] << "), (" << points[0][1] << ")] and 2 " << "[(" << points[1][0] << "), (" << points[1][1] << ")] " << (intersect ? "do" : "don't") << "intersect\n" << std::endl; // Double new line intended, Prints: "The lines 1 [(x,y), (x,y)] and 2 [(x,y), (x,y)] do/don't intersect"
}
end: return 0;
}
Explaination
std::ostream& operator<<.....: Make Point ostreamable (usable with cout).
Point points[2][2]: a 2 x 2 point array (2 lines, 2 points each)
string line: a string for user input
while (true): repeat the cycle of "Get input, Check if lines intersect" (remove it if you want the program to exit after completing the cycle once)
The cycle:
A. Get input:
2 nested loops, one for lines, the other for points
Print Line i, Point j (x,y):
std::getline: Read till the user presses enter
If the input is empty, terminate the program
Read a number into point.x, ignore the ',' then read another number into point.y
B. Check if lines intersect
Use the doIntersect and save the result into a variable
Print: The lines 1 [(x,y), (x,y)] and 2 [(x,y), (x,y)] do/don't intersect where (do/don't) depends on whether the result is true (lines intersect) or not
how can i modify this part so it will ask user to input the values of point
You can do this by using operator overloading. In particular you can overload operator>> as shown below. The below shown program asks for input from user and use those point entered by the user to check if they intersect or not.
#include <iostream>
using namespace std;
struct point
{
int x, y;
//default constructor
point(): x(0), y(0)
{
}
//overload operator>>
friend std::istream &operator>>(std::istream &is, point& inputPoint);
};
int orientation(point p1, point p2, point p3)
{
int val = (p2.y - p1.y) * (p3.x - p2.x) -
(p2.x -p1.x) * (p3.y -p2.y);
if (val == 0) return 0;
return (val > 0)? 1: 2;
}
bool validprojection(int a, int b, int c, int d)
{
if (a > b)
swap(a,b);
if (c > d)
swap(c, d);
return max(a, c) <= min(b, d);
}
bool doIntersect(point a, point b, point c, point d)
{
int o1 = orientation(a, b, c);
int o2 = orientation(a, b, d);
int o3 = orientation(c, d, a);
int o4 = orientation(c, d, b);
if(o1 != o2 && o3 != o4)
return true;
if (o1 == 0 && o4 == 0)
{
if(validprojection(a.x, b.x, c.x, d.x) && validprojection(a.y, b.y, c.y, d.y))
return true;
}
return false;
}
//define overloaded operator>>
std::istream &operator>>(std::istream &is, point& inputPoint)
{
std::cout<<"Enter x value: ";
std::cin >> inputPoint.x ;
std::cout<<"Enter y value: ";
std::cin >> inputPoint.y;
//check if input succeeded
if(cin)
{
//do something if needed
;
}
else
{
inputPoint = point();//otherwise leave the object in DEFAULT STATE
}
return is;
}
int main()
{
cout<<"To find the intersection point of two line segment"<<std::endl;
//TAKE INPUT(x and y values) FROM USER
point p1;
std::cin >> p1;
point p2;
std::cin >> p2;
point p3;
std::cin >> p3;
point p4;
std::cin >> p4;
//check if intersect
doIntersect(p1, p2, p3, p4)? cout << "yes\n": cout<< "No\n";
//AGAIN TAKE INPUT FROM USER
std::cin >> p1;
std::cin >> p2;
std::cin >> p3;
std::cin >> p4;
doIntersect(p1, p2, p3, p4)? cout << "yes\n": cout<< "No\n";
return 0;
}
The output of the above program can be seen here.

error - f was not declared in this scope - secant method

I am currently working out irr using algorithms through secant method. I think I am doing it correctly so far? but my main problem is that it keeps saying f is not declared in this scope:
int fx1 =f (x1);
int fx2 =f (x2);.
when i try to declare f as a function it does not allow me to, can anyone help?
#include iostream
#include iomanip
#include cmath
using namespace std;
const int Max_Iter=1000;
const double e=0.001;
double internal_r(double c, double r, int n){
double internal_r = 0.0;
for (n=1; n<=Max_Iter; n++); {
internal_r -= c/pow(1.0+r, n);
}
return internal_r;
}
int Secant(double x1, double x2, double e, double &root) {
int fx1 =f (x1);
int fx2 =f (x2);
if (x1==x2|| f(x2)==f(x1)){
root=0; return 0;
}
double x = x1 - f(x1) - (x2-x1) / (f(x2)-f(x1));
if ( fabs(f(x)) < e){
root = x; return 1;
} else {
if (f(x1)*f(x)<0){
return Secant(x1,x,e,root);
} else {
return Secant (x,x2,e,root);
}
}
}
int main() {
int n = 1;
double x1 = 0.0, x2 = 0.0, x = 0.0, fx1 = 0.0, fx2 = 0.0;
cout << "Secant Method" << endl;
cout <<"Enter first initial approximation: ";
cin >>x1;
cout <<"Enter second initial approximation: ";
cin >>x2;
cout <<"Enter the iteration number: ";
cin >>n;
if (n>=0 && n<=Max_Iter) {
cout << "you have entered an iteration sucessfully\n";
x = x1 - (fx1 * (x2 - x1)) / (fx2 - fx1);
cout <<"\n The root of the equation is "<< x <<endl;
return 0;
}
}

How to run without vectors with c++

Is there a way to execute this code without using vectors?
Can this program be run without vectors in the polygon class?
If possible, how should I modify the code?
And is it right to write the copy constructor and the move constructor as it is now?
It's so hard to do C++ while playing Python. Help me.
Thank you.
Polygon.h
#pragma once
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
struct C2D {
double x, y;
};
class Polygon {
int point;
vector<C2D> arr;
public:
Polygon(int point_, C2D arr_[]) : arr(point_) {
point = point_;
memcpy(arr.data(), arr_, sizeof(C2D) * point);
};
Polygon(Polygon& p) : arr(p.point) {
point = p.point;
memcpy(arr.data(), p.arr.data(), sizeof(C2D) * point);
};
Polygon(Polygon&& p) {
point = p.point;
memcpy(arr.data(), p.arr.data(), sizeof(C2D) * point);
p.point = 0;
delete[]p.arr.data();
};
void print() const {
cout << "Polygon information" << endl;
for (int i = 0; i < point; i++) {
cout << i + 1<< "point" << " : " << arr[i].x << ", " << arr[i].y << endl;
}
cout << endl;
};
double area_result() {
double sum = 0;
for (int i = 1; i < point; i++) {
sum += ccw(arr[0].x, arr[i - 1].x, arr[i].x, arr[0].y, arr[i - 1].y, arr[i].y);
}
return fabs(sum);
}
static double ccw(double x1, double x2, double x3, double y1, double y2, double y3) {
double res = x1 * y2 + x2 * y3 + x3 * y1;
res += (-y1 * x2 - y2 * x3 - y3 * x1);
return res / 2;
}
};
main.cpp
int main() {
int point;
C2D* c2d;
cout << "point : ";
cin >> point;
cout << endl;
c2d = new C2D[point];
for (int i = 0; i < point; i++) {
cout << i + 1 << "x : ";
cin >> c2d[i].x;
cout << i + 1 << "y : ";
cin >> c2d[i].y;
cout << endl;
}
cout << endl;
Polygon p(point, c2d);
p.print();
cout << "Polygon area : " << p.area_result() << endl;
return 0;
}
Don't.
Vectors are one of those no-brainer improvements of C++ over C. Don't try to code around them, learn how to use them properly. You will see that many lines of code and many sources of headaches go away when you actually code C++.
Polygon.hpp
#ifndef POLYGON_HPP
#define POLYGON_HPP
#include <iostream>
#include <vector>
#include <cmath>
struct C2D
{
double x, y;
};
class Polygon
{
public:
Polygon( unsigned points_, std::vector<C2D> const & arr_ ) : points( points_ ), arr( arr_ ) {}
Polygon( Polygon & p ) : points( p.points ), arr( p.arr ) {}
Polygon( Polygon && p ) : points( p.points )
{
arr.swap( p.arr );
}
friend std::ostream & operator<<( std::ostream & out, Polygon const & p );
double area_result()
{
double sum = 0;
for ( unsigned i = 1; i < points; ++i )
{
sum += ccw( arr[0].x, arr[i - 1].x, arr[i].x, arr[0].y, arr[i - 1].y, arr[i].y );
}
return std::fabs( sum );
}
static double ccw( double x1, double x2, double x3, double y1, double y2, double y3 )
{
double res = x1 * y2 + x2 * y3 + x3 * y1;
res += ( -y1 * x2 - y2 * x3 - y3 * x1 );
return res / 2;
}
private:
unsigned points;
std::vector<C2D> arr;
};
#endif
main.cpp
#include "Polygon.hpp"
#include <vector>
#include <iostream>
std::ostream & operator<<( std::ostream & out, Polygon const & p )
{
out << "Polygon information" << std::endl;
for ( unsigned i = 0; i < p.points; ++i )
{
out << ( i + 1 ) << "point : " << p.arr[i].x << ", " << p.arr[i].y << std::endl;
}
out << std::endl;
return out;
}
int main()
{
int points;
std::vector<C2D> c2d;
std::cout << "points : ";
std::cin >> points;
c2d.reserve( points );
for (int i = 0; i < points; i++) {
C2D coord;
std::cout << i + 1 << "x : ";
std::cin >> coord.x;
std::cout << i + 1 << "y : ";
std::cin >> coord.y;
c2d.push_back( coord );
}
Polygon p( points, c2d );
std::cout << p << "Polygon area : " << p.area_result() << std::endl;
return 0;
}
Your code is using vector exactly like a C style array, so you can replace it with such an array with minimum changes.
In fact, it will make your code simpler to read, since you will not be misusing a C++ object like a C variable.
class Polygon {
int point;
C2D *arr;
public:
Polygon(int point_, C2D arr_[]) {
point = point_;
arr = new C2D[point];
//you should check here allocation is successful
memcpy(arr, arr_, sizeof(C2D) * point);
};
Polygon(Polygon& p) {
point = p.point;
arr = new C2D[point];
memcpy(arr, p.arr, sizeof(C2D) * point);
};
Polygon(Polygon&& p) {
point = p.point;
arr = p.arr;
p.point = 0;
p.arr = null;
};
//you will need to add a destructor to clean up memory
~Polygon() {
delete [] arr;
}
};
That said, as the comments suggest, this is a bad practice.
If you have some constraints, such as a limited C++ environment lacking a vector implementation, a need to interface your code with another language / runtime, or homework requirement, you should add them to your question for suggestions on better solution.

How to round float to up and down value c++ with own function?

double round(double a)
{
double b, c, f, g;
float d[2];
c = modf(a, &b);
if (a > 0) {
f = a - c;
g = a - c + 1;
d[0] = f;
d[1] = g;
return d[0], d[1];
}
else {
f = a - c;
g = a - c - 1;
d[0] = f;
d[1] = g;
return d[0], d[1];
}
}
I need to get 2 numbers it the end(for ex: if I have num 12.34, I want to get 12 and 13)This is my function of rounding for pos and neg numbers. But it returns only 1 value(( So I'm stack...pls, help how to return 2 values?
You cannot return two things in the return, so return d[0],d[1] compiles but doesn't work as you expect. You can use two reference parameters in the function prototype to return. Something like void round(double a, double* result1, double* result2). Into the function, set d[0] to *result1 and d[1] to *result2.
Another thing: Are you sure the line g = a - c - 1; when a is negative is correct? I think you need to do g = a + c - 1;, because a is negative.
#include "pch.h"
#include <iostream>
#include <array>
using namespace std;
auto rounding(double x)
{
int part = static_cast<int>(x);
if (x < 0.0)
{
return array<int, 2> {
part - 1, part
};
}
else
{
return array<int, 2> {
part, part + 1
};
}
}
int main()
{
double x;
cout << "Please, enter a float number to round: ";
cin >> x;
auto r1 = rounding(x);
if (x > 0) {
cout << "A lower value: " << r1[0] << endl << "A bigger value: " << r1[1];
}
else {
cout << "A bigger value: " << r1[0] << endl << "A lower value: " << r1[1];
}
}

Overload in function on a class type

#include <iostream>
#include <iomanip>
#include <cmath>
#include "lineType.h"
using namespace std;
int main()
{
double x, y;
double a = 1.;
double b = 0.;
double c = 1.;
double d = 2.;
double e = 0.;
double f = 3.;
double g = 0.;
double h = 4.;
double i = -1.;
lineType line1(a, b, c);
lineType line2(d, e, f);
lineType line3(g, h, i);
cout << "Line 1: ";
line1.display();
if (line1.isParallel(line2)) cout << "line1 is parallel to line 2" << endl;
if (line1.isPerp(line3)) cout << "line 1 is perpendicular to line 3" << endl;
if (line2.intersect(line3, x, y))
cout << "The intersection of lines 2 and 3 is at point(" << x << ", " << y << ")" << endl;
else
cout << "Lines 2 and 3 do not intersect." << endl;
return 0;
}
This is the code I am testing and the issue I am getting is c2661 no overloaded function takes 3 arguments
My Header file is:
#pragma once
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
class lineType
{
private:
double a;
double b;
double c;
public:
void display() const;
bool isParallel(const lineType& line) const;
bool isPerp(const lineType& line) const;
bool intersect(const lineType& line, double& x, double& y);
lineType();
lineType(double a2, double b2, double c2);
~lineType();
};
This is the lineType.cpp file that was wanted
#include "lineType.h"
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
void lineType::display() const
{
cout << a << "x + " << b << "y = " << c << endl;
}
bool lineType::isParallel(const lineType& line) const
{
if (a == 0 && line.a == 0)
return 1;
if (b == 0 && line.b == 0)
return 1;
else if (-a / b == -line.a / line.b)
return 1;
else
return 0;
}
bool lineType::isPerp(const lineType& line) const
{
if (a == 0 && line.b == 0)
return 1;
if (b == 0 && line.a == 0)
return 1;
else if (-a / b == line.b / line.a)
return 1;
else
return 0;
}
bool lineType::intersect(const lineType& line, double& x, double& y)
{
if (a == 0)
x = c / b;
if (line.a == 0)
x = line.c / line.b;
if (b == 0)
y = c / a;
if (line.b == 0)
{
y = line.c / line.a;
}
else
{
x = ((a*line.c) - (c*line.a)) / ((b*line.a) - (a*line.b));
y = ((c*line.b) - (b*line.c)) / ((b*line.a) - (a*line.b));
}
if (a == 0 && line.a == 0)
return 0;
if (b == 0 && line.b == 0)
return 0;
return 1;
}
lineType::lineType()
{
a = 0;
b = 0;
c = 0;
}
lineType::lineType(double a2, double b2, double c2)
{
a = a2;
b = b2;
c = c2;
}
lineType::~lineType()
{
}
The error message that appears
Error (active) E0289 no instance of constructor "lineType::lineType" matches the argument list Project1 line 20
Same error message for lines 21 and 22 in the source.cpp file. so I am not sure what is occuring?
lineType::lineType, which is the constructor, is implicitely generated, since you did not provide any user defined constructors. Default-generated constructors take no arguments, yet you try to provide three arguments in lines:
lineType line1(a, b, c);
lineType line2(d, e, f);
lineType line3(g, h, i);
I suspect you wanted to take advantage of aggregate initialisation, which you can't unfortunately use, since your a, b and c variables are private. You might want to add such constructor yourself:
lineType(const double a, const double b, const double c)
:a(a), b(b), c(c) { }
But that's not all. You have couple more problems with your code. Notably:
if (line1.isParallel(line2)) cout << "line1 is parallel to line 2" << endl;
contains a typo. It should be isParrallel, as declared in your class (which is also a typo) instead of isParallel. Fix either of these.
Lastly, the line:
if (line2.intersect(line3, x, y))
will not compile, since intersect() returns void, not bool. if statements require that they are provided either bools or something that's implicitely convertible to bool type. Make your function return bool, which is the logical assumption for a function that's name starts with is.