Sweep Line algorithm [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
SWEEP LINE EXAMPLE WITH EXAMPLE: AFTER CORRECTION
The code Contais 3 classes:
Class Line to represent the Horizontal lines: Parameters:
(x1,y1)----------(x2,y2)
Class Point:
Class segment for the sweep line algorithm
I am trying to use the following code, to compute the intersections between horizontal lines, As you can from the coordinates that My lines are Horizontal:
Coordinates: x1,y1,x2,y2 I have x1 < x2, and y1 = y
Class Point:
#ifndef POINT_H
#define POINT_H
class Point
{
public:
Point(float, float);
float x;
float y;
};
#endif // POINT_H
#include "Point.h"
Point::Point(float xi, float yi):x(xi),y(yi)
{
}
Class Line
#ifndef LINE_H
#define LINE_H
class Line
{
public:
Line(int,int,int,int);
int x1, y1, x2, y2;
};
#endif // LINE_H
#include "Line.h"
Line::Line(int x_1, int y_1, int x_2,int y_2):x1(x_1),y1(y_1),x2(x_2),y2(y_2)
{
//ctor
}
Class Segment:
#ifndef SEGMENT_H
#define SEGMENT_H
#include "Point.h"
#include "Line.h"
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
enum event_type { EVENT_END,EVENT_VERTICAL,EVENT_START};
struct event
{
event_type type;
int x;
int line; // index into list of lines
event() {}
event(event_type type, int x, int line) : type(type), x(x), line(line) {}
// sort by X then by type
bool operator <(const event &b) const
{
if (x != b.x) return x < b.x;
else return type < b.type;
}
};
class Segment
{
public:
Segment();
vector<Point> hv_intersections(const vector<Line> &);
};
#endif // SEGMENT_H
#include "Segment.h"
Segment::Segment()
{
//ctor
}
vector<Point> Segment::hv_intersections(const vector<Line> & lines)
{
int L = lines.size();
vector<event> events;
vector<Point> ans;
// Y coordinates of active lines
multiset<int> active;
// Convert lines into events
for (int i = 0; i < L; i++)
{
if (lines[i].y1 != lines[i].y2)
events.push_back(event(EVENT_VERTICAL, lines[i].x1, i));
else if (lines[i].x1 != lines[i].x2)
{
events.push_back(event(EVENT_START, lines[i].x1, i));
events.push_back(event(EVENT_END, lines[i].x2, i));
}
}
// Sort events by X
sort(events.begin(), events.end());
// Returns all intersections between lines. The lines must all be either
// horizontal and vertical, and only horizontal-vertical intersections are
// counted (i.e. not overlaps). Lines are considered to exclude their
// endpoints. Also, each line must have x1 <= x2 and y1 <= y2.
for (vector<event>::const_iterator e = events.begin(); e != events.end(); ++e)
{
switch (e->type)
{
case EVENT_START:
active.insert(lines[e->line].y1);
break;
case EVENT_END:
active.erase(active.find(lines[e->line].y1));
break;
case EVENT_VERTICAL:
{
// Iterate over all y values for intersecting horizontal lines
multiset<int>::const_iterator first, last, i;
first = active.upper_bound(lines[e->line].y1);
last = active.lower_bound(lines[e->line].y2);
for (i = first; i != last; ++i)
ans.push_back(Point(e->x, *i));
}
break;
}
}
return ans;
}
int main()
{
vector<Line> v;
v.push_back(Line(0, 5, 10, 5));
v.push_back(Line(5, 0, 5, 10));
Segment s;
vector<Point> p = s.hv_intersections(v);
cout << p.size() << endl;
return 0;
}

The code is correct (assuming you have proper #include and main() methods). The lines you provided have no intersections. If you add any vertical line like 800 100 800 2000 you will get a vector<pnt> of intersections.

Parallel lines (in this case horizontal lines) do not intersect. Never.
http://en.wikipedia.org/wiki/Parallel_(geometry)

Related

OOP in C++ newbie [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 days ago.
Improve this question
I'm a newcomer in C++ OOP and I try to do assignment from my prof.
The prof asked me to create a program that prompt the users to input the number of vertex of a polygon and also its vertices in 2D. That's all.
For example:
Number of points: 3
Enter vertex 1 coordinate: 1 1
Enter vertex 2 coordinate: 1 2
...
I have tried to create 5 files: Point2D.cpp; Point2D.h; Polygon.cpp; Polygon.h and main.cpp
Point2D.cpp
#include "Point2D.h"
#include <iostream>
using namespace std;
Point2D::Point2D(float newX, float newY) {
cout << "calling float type" << endl;
}
void Point2D::setX(float val) {
x = val;
}
float Point2D::getX() {
return x;
}
void Point2D::setY(float val) {
y = val;
}
float Point2D::getX() {
return y;
}
Point2D.h
#pragma once
class Point2D {
private:
float x, y;
public:
// constructor with parameter + default
Point2D(float newX = 0, float newY = 0);
void setX(float val);
float getX();
void setY(float val);
float getY();
};
Polygon.cpp
#include "Polygon.h"
#include <iostream>
Polygon::Polygon() {
verticesCount = 0;
verticesList = NULL;
}
Polygon::Polygon(int vCount) {
if (vCount > 0) {
verticesCount = vCount;
// allocate memory for verticesList
if (verticesList != NULL)
delete[] verticesList;
verticesList = new Point2D[verticesCount];
}
}
Point2D Polygon::getVertex(int index) {
if (verticesCount <= 0) {
return NULL;
} if (verticesList = NULL) {
return NULL;
} if (index >= verticesCount) {
return NULL;
}
return verticesList[index];
}
Polygon::~Polygon() {
}
Polygon.h
#pragma once
#include "Point2D.h"
class Polygon {
private:
Point2D* verticesList;
int verticesCount;
public:
Polygon();
Polygon(int vCount);
~Polygon();
Point2D getVertex(int index);
void addPoint(Point2D p);
};
main.cpp
#include <iostream>
#include "Point2D.h"
#include "Polygon.h"
using namespace std;
int main() {
// using default constructor
Point2D p = Point2D();
return 0;
}
I want to ask from you guys that if my code is correct or not. And what should I do next from there?
Thanks in advance!

c++ LNK2019 error between two classes in same project

So I'm trying to create a program that mimics the Minesweeper game. I have double-checked the header files, the class names, and made sure the headers are #included in the other cpp files, but when I try to build the program, I get a LNK2019 error in the "Main" class I have.
Error in full:
Error 1 error LNK2019: unresolved external symbol "public: __thiscall
Board::Board(int,int,int)" (??0Board##QAE#HHH#Z) referenced in
function _main \fpsb\g\gathmr26\visual studio
2013\Projects\Minesweeper\Minesweeper\Main.obj Minesweeper
I've spent probably around 2 hours looking at answers here on StackOverflow and elsewhere and got nowhere. I've run down through every bullet point in this MSDN page, and every "common cause" in this popular answer, and none of them seemed to apply to my situation. I've also tried all the "Diagnosis tools" options on the MSDN page and all they've done is just confuse me more.
The closest I have to my situation (as far as I can tell) is this question except that all of my code is just in one project, not multiple. One of the people who answered that question has said "I typed this code into my Visual Studio and it worked fine", having assumed that the files were in one project. I don't understand why that answer got it working there when I have pretty much the same situation here.
So, anyway, here is the code:
Main.cpp
#include <iostream>
#include <string>
#include "Cell.h"
#include "Board.h"
int main() {
Board *bee;
bee = new Board(50, 50, 50);
std::cout << "board created";
return 0;
}
Board.cpp
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
using namespace std;
#include "Cell.h"
#include "Board.h"
#ifndef BOARD_H
#define BOARD_H
// Board class. Used to create an array of cell objects to function as data model for Minsweeper game.
class Board
{
private:
int width; // number of columns in board
int height; // number of rows in board
int mines; // number of mines stored in board
Cell*** cells; // array storing cell objects
public:
// Constructor for board. Takes number of columns, rows, and mines as parameters
Board::Board(int cols, int rows, int numMines) {
width = cols;
height = rows;
mines = numMines;
cells = new Cell**[height];
for (int i = 0; i < height; i++) {
cells[i] = new Cell*[width];
}
int c = 0;
int r = 0;
while (r < height)
{
while (c < width)
{
setCell(c, r, CellValue::COVERED_CELL);
c++;
}
c = 0;
r++;
}
int m = 0;
while (m < numMines)
{
std::srand(std::time(nullptr));
int x = generateRandomNumberInRange(0, width - 1);
int y = generateRandomNumberInRange(0, height - 1);
if (!(getCellVal(x, y) == MINE))
{
setCell(x, y, CellValue::MINE);
m++;
}
}
}
// Accessor for width field
int Board::getWidth()
{
return width;
}
// Accessor for height field
int Board::getHeight()
{
return height;
}
// Accessor for mines field
int Board::getMines()
{
return mines;
}
// Function to access value of cell located in array where x is column parameter and y is row parameter
CellValue Board::getCellVal(int x, int y)
{
CellValue value = CellValue::INVALID_CELL;
if (!(x < 0 || x >(width - 1) || y < 0 || y >(height - 1)))
{
Cell temp = *cells[x][y];
value = temp.getValue();
}
return value;
}
// Function to set value of cell located in array where x is column parameter and y is row parameter
void Board::setCell(int x, int y, CellValue value)
{
if (!(x < 0 || x >(width - 1) || y < 0 || y >(height - 1)))
{
Cell temp = *cells[x][y];
temp.setValue(value);
}
}
// Function to determine if game is lost
// Loops through array to see if there are any UNCOVERED_MINES
// If so, returns true, game ends, as you've lost :(
// If not, returns false and game can continue
// Should run after every click action in game
bool Board::isGameLost()
{
bool isLost = false;
int c = 0;
int r = 0;
while (r < height)
{
while (c < width)
{
if (getCellVal(c, r) == UNCOVERED_MINE)
{
isLost = true;
}
c++;
}
c = 0;
r++;
}
return isLost;
}
// Function to determine if game is won
// Loops through array to determine if there are any falsely flagged mines, unflagged mines, covered cells, or uncovered mines
// If there are, returns false and game continues
// If not, returns true, games ends, you've won :)
bool Board::isGameWon()
{
bool isWon = true;
int c = 0;
int r = 0;
while (r < height)
{
while (c < width)
{
CellValue value = getCellVal(c, r);
if ((value == FLAG) ||
(value == MINE) ||
(value == COVERED_CELL) ||
(value == UNCOVERED_MINE))
{
isWon = false;
}
c++;
}
c = 0;
r++;
}
return isWon;
}
};
#endif
Board.h
#include <iostream>
#include <string>
#include "Cell.h"
#ifndef BOARD_H
#define BOARD_H
class Cell;
enum CellValue;
class Board
{
private:
int width;
int height;
int mines;
Cell*** cells;
public:
Board(int cols, int rows, int numMines);
int getWidth();
int getHeight();
int getMines();
CellValue* getCellVal(int x, int y);
void setCell(int x, int y, CellValue value);
void uncoverCell(int x, int y);
void flagCell(int x, int y);
bool isGameLost();
bool isGameWon();
};
#endif
I know this is a common error that people have and that there's more than a handful of questions about this on StackOverflow, but at this point, I've not found any that seem to match what I have here. What is the issue here?
Seems like you're mixing header and source files. Your cpp file contains a class declaration with all the functions defined inside. This is not what a cpp file looks like. It should only contain function declarations:
Board::Board(...)
{
...
}
bool Board::IsGameWon...
etc...

For-Loop Segmentation -- Excessive run ( i < SIZE, but i = SIZE)

This is a function in a program replicating Sierpinski's gasket. This function is supposed to attach the points in the triangle for the fractal.
After much deliberation I've figured out where the issue lies:
void add_pts(int &x, int &y)
{
Vector_ref<Rectangle> pt;
for (int i = 0; i < POINTS; ++i)
{
pt_test; //generates changing x, y vals within the limits of the triangle
cout << "pass" << i <<endl;
pt.push_back(new Rectangle(Point(x,y),5,5));
pt[i].set_fill_color(Color::yellow);
win.attach(pt[i]);
}
}
The output is "pass1...pass[POINTS-1]", but for whatever reason it runs when i = POINTS and runs into the segmentation error. I have no clue as to why. Can anyone assist, please?
Here is my code. The pt_test and coord are a bit sloppy but seeing as it can't run properly it's very hard to ascertain what I can streamline.
#include <stdlib.h>
#include <iostream>
#include <cmath>
#include <iomanip>
#include <time.h>
#include "Simple_window.h"
#include "Graph.h"
#include "Point.h"
#include "GUI.h"
#include "Window.h"
using namespace std;
using namespace Graph_lib;
// globals
const int POINTS = 5000;
unsigned int seed = (unsigned int)time(0);
Simple_window win(Point(100,100),1100,700,"Homework 9");
// function declarations
double random(unsigned int &seed);
bool coords(int &x, int &y);
void pt_test(int x, int y);
void add_pts(int &x, int &y);
int main()
{
int x, y;
// title
Text title(Point(400,50), "The Sierpinski Gasket");
title.set_font(Graph_lib::Font::helvetica_bold);
title.set_font_size(25);
title.set_color(Color::cyan);
win.attach(title);
// triangle
Closed_polyline tri;
tri.add(Point(250,75)); // A
tri.add(Point(850,75)); // B
tri.add(Point(550,675)); // C
tri.set_fill_color(Color::white);
tri.set_color(Color::dark_red);
tri.set_style(Line_style(Line_style::solid,3));
win.attach(tri);
// vertices
Text vert_a(Point(225,70), "A (250, 75)");
vert_a.set_font(Graph_lib::Font::helvetica_bold);
vert_a.set_font_size(15);
vert_a.set_color(Color::cyan);
Text vert_b(Point(855,70), "B (850, 75)");
vert_b.set_font(Graph_lib::Font::helvetica_bold);
vert_b.set_font_size(15);
vert_b.set_color(Color::cyan);
Text vert_c(Point(575,670), "C (550, 675)");
vert_c.set_font(Graph_lib::Font::helvetica_bold);
vert_c.set_font_size(15);
vert_c.set_color(Color::cyan);
win.attach(vert_a);
win.attach(vert_b);
win.attach(vert_c);
// point selection
add_pts(x, y);
// window title and display
win.wait_for_button();
}
double random(unsigned int &seed)
{
const int MODULUS = 15749;
const int MULTIPLIER = 69069;
const int INCREMENT = 1;
seed = ((MULTIPLIER*seed)+INCREMENT)%MODULUS;
return double(seed)/double(MODULUS);
}
bool coords(int &x, int &y) // generates the points
{
x = int(251 + 600*random(seed));
y = int(76 + 600*random(seed));
if( y > (2*x-425) && x<= 550 || x>=550 && y < (-2*x + 1775))
return true;
}
void pt_test(int x, int y) // tests the points until they are within the range
{
coords;
while(coords == 0)
coords;
}
void add_pts(int &x, int &y) // attaches the points as shapes
{
Vector_ref<Rectangle> pt;
for (int i = 0; i < POINTS; ++i)
{
pt_test;
cout << "i == " << i << " points == " << POINTS << endl;
pt.push_back(new Rectangle(Point(x,y),5,5));
pt[i].set_fill_color(Color::yellow);
win.attach(pt[i]);
}
}
I've also noticed that the function add_pts doesn't work when the body is in the loop, but if you put the body in int_main(), it runs indefinitely but doesn't reach the segmentation fault as quickly, if at all.

c++ finding distance between 2 points

In my test program I have two points, and I want to find distance between them with my distancefrom. But I get answer 0.
Why does it give 0?
How can I fix it?
Point<2> v1;
// this should have {0.0, 0.0}
Point<2> v3 { list{2.0,3.0} };
float f = v1.distanceFrom(v3);
cout << f << endl;
I have a point.h file.
#ifndef POINT_H
#define POINT_H
#include <iostream>
#include <list>
#include <sstream>
#include <string>
using std::stringstream;
#include <cmath>
using namespace std;
template<unsigned short n>
class Point {
public:
list <float> coords = {0.0};
Point <n>() = default;
Point <n>(list<float> coords){
if (coords.size()!=n) {
throw string ("Vale koordinaatide arv");
}
this-> coords=coords;
}
string toString(){
string sone;
ostringstream ss;
sone.append("(");
auto it3= coords.begin();
while ((it3) != coords.end()){
ss << (*it3);
sone.append(ss.str());
ss.str("");
sone.append(",");
++it3;
}
sone.pop_back();
sone.append(")");
return sone;
}
float distanceFrom (Point <n> v){
float s=0;
list<float> coords;
auto it1= coords.begin();
auto it2= v.coords.begin();
while ((it1) != coords.end()){
s+=(*it1 -*it2)*(*it1-*it2);
it1++;
it2++;
}
return sqrt(s);
}
friend std::ostream& operator <<(std::ostream& out, const Point<n>& v)
{
out << "("<<"Test"<<")";
return out;
}
};
#endif
First, your coords list does not know you want its size to be n. Its size after default initialization like the following is 1:
list <float> coords = {0.0};
The proper way to construct it would be:
list <float> coords = list <float> (n, 0.0);
Second, you allocate a new coords inside the function distanceFrom:
list<float> coords;
This shadows the real coords of the point which you in fact want to use. Remove that line, and you will be fine.
#include<iostream>
#include<cstdlib>
#include<cmath>
using namespace std;
class pointDistance{
int x, y;
public:
pointDistance (int a, int b){
x =a;
y =b;
}
void pointShow(){
cout<<"The Point is ("<<x<<","<<y<<")"<<endl;
}
friend void Distance(pointDistance , pointDistance);
};
//formula of distance between two points:
//d =((x1^2 - x2^2) + (y1^2 - y2^2))^1/2
void Distance(pointDistance o1, pointDistance o2)
{
// pointDistance o3;
int d1,d2;
d1 = (o1.x -o2.x)*(o1.x -o2.x);
d2 = (o1.y - o2.y)*(o1.y - o2.y);
cout<<"So the distance between two point is "<< sqrt(d1+d2)<<endl;
}
int main(){
pointDistance one(4,5);
one.pointShow();
pointDistance two(0,6);
two.pointShow();
Distance(one, two);
return 0;
}

Unable to push_back elements in a list

I'm facing a really peculiar problem with my code,
I am unable to push elements into a list.
I'm trying to implement a scan fill algorithm.
I want the list of points that I have plotted on the screen so that I can check if a scan line intersects with them.
In my Screen::plot_pixel function I push the Point into the plotted_points list.
But when I iterate through the list, it's empty.(I'm iterating in shape.cpp using a friend function)
I tried using a set too but to no avail. I have attached the console output I get too.
plot_pixel gets called multiple times, I verified this by adding a print statement there but the points refuse to get pushed in.
Here's all my code, point.h
#ifndef POINT_H
#define POINT_H
class Point
{
float x_coordinate,y_coordinate;
public:
Point(){}
Point(float x, float y):x_coordinate(x),y_coordinate(y){}
float get_x() const{return x_coordinate;}
float get_y() const {return y_coordinate;}
bool operator==(const Point rhs)const
{
if( ((int)x_coordinate == (int)rhs.get_x()) && ((int)y_coordinate == (int)rhs.get_y()) )
return true;
else return false;
}
bool operator<(const Point rhs)const
{
if((int)x_coordinate < (int)rhs.get_x())
return true;
else return false;
}
};
#endif
screen.h
#ifndef SCREEN_H
#define SCREEN_H
#include<graphics.h>
#include "point.h"
#include<list>
class Shape;
class Screen
{
private:
int max_x,max_y,grid_size;
int delta_x,delta_y;
int origin_x,origin_y;
public:
std::list<Point> plotted_points;
// Default Constructor to Initialize the screen with the grid
Screen(int, int, int);
//Method prototypes
void plot_pixel(int,int,int);
void dda_line(Point p1, Point p2);
int get_max_x(){return max_x;}
int get_max_y(){ return max_y;}
friend void draw_shape(Screen,Shape);
friend void fill_shape(Screen,Shape);
};
#endif
screen.cpp
#include "screen.h"
void Screen::plot_pixel(int xcoord,int ycoord,int col=WHITE)
{
int l,t,r,b;
l = origin_x + xcoord * delta_x;
r = l + delta_x;
b = origin_y - ycoord * delta_y;
t = b - delta_y;
setcolor(col);
bar(l,t,r,b);
setcolor(WHITE);
Point *tmp = new Point(xcoord,ycoord);
//the culprit code
plotted_points.push_back(*tmp);
delete tmp;
}
void Screen::dda_line(Point p1, Point p2)
{
.....
plot_pixel(x,y,0);
}
shape.h
#ifndef SHAPE_H
#define SHAPE_H
#include<list>
#include<iostream>
#include "point.h;
class Screen;
class Shape
{
list<Point> figure;
public:
Shape(list<Point> s);
friend void draw_shape(Screen,Shape);
friend void fill_shape(Screen,Shape);
};
#endif
shape.cpp
#include "shape.h"
#include "screen.h"
Shape::Shape(list<Point> s):figure(s){}
void fill_shape(Screen scr, Shape sh)
{
list<Point>::iterator pit,vit;
//HERE's Where I try iterating over the list and get nothing
//to check if the plotted points and vertices are listed correctly
cout<<"Plotted Points :\n";
for( pit = scr.plotted_points.begin();pit != scr.plotted_points.end();pit++)
{
cout<<pit->get_x()<<" "<<pit->get_y()<<endl;
}
cout<<"Vertices :\n";
for( vit = sh.figure.begin();vit != sh.figure.end();vit++)
{
cout<<vit->get_x()<<" "<<vit->get_y()<<endl;
}
}
and finally my driver
#include "screen.h"
#include "shape.h"
using namespace std;
int main()
{
Screen s(641,641,32);
Point p1(-10,-10),p2(-10,10),p3(10,10),p4(10,-10);
list<Point> rectangle_points;
//to construct the rectangle
rectangle_points.push_back(p1);
rectangle_points.push_back(p2);
rectangle_points.push_back(p3);
rectangle_points.push_back(p4);
Shape rectangle(rectangle_points);
draw_shape(s,rectangle);
fill_shape(s,rectangle);
getch();
return 0;
}
Here's the output
Plotted Points :
Vertices :
-10 -10
-10 10
10 10
10 -10
You are passing the Screen object s into your functions, but they take the Screen object by value. They therefore take a copy of the object which they then modify. Your original Screen "s" is unchanged after the call to draw_shape().
You should probably modify them so they take a reference to a Screen object, such as:
void draw_shape(Screen& scr, Shape shp)