Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
There are some spherical balloons taped onto a flat wall that represents the XY-plane. The balloons are represented as a 2D integer array points where points[i] = [xstart, xend] denotes a balloon whose horizontal diameter stretches between xstart and xend. You do not know the exact y-coordinates of the balloons.
Arrows can be shot up directly vertically (in the positive y-direction) from different points along the x-axis. A balloon with xstart and xend is burst by an arrow shot at x if xstart <= x <= xend. There is no limit to the number of arrows that can be shot. A shot arrow keeps traveling up infinitely, bursting any balloons in its path.
Given the array points, return the minimum number of arrows that must be shot to burst all balloons
bool compare(vector<int> &a,vector<int> &b){
return a[1]<=b[1];
}
class Solution {
public:
int findMinArrowShots(vector<vector<int>>& points) {
if(points.size()==1) return 1;
sort(points.begin(),points.end(),compare);
int arrows=1,end=points[0][1];
for(int i=1;i<points.size();i++){
if(points[i][0]>end){
arrows++;
end=points[i][1];
}
}
return arrows;
}
};
I am getting a runtime error:
Line 1034: Char 34: runtime error: applying non-zero offset 4 to null pointer (stl_vector.h)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:1043:34
bool compare(vector<int> &a,vector<int> &b){
return a[1]<=b[1];
}
should be
bool compare(const vector<int> &a, const vector<int> &b){
return a[1]<b[1];
}
Comparators must define a strict weak ordering. One consequence of that is that they must return false for equal values, so <= is incorrect.
Looking at the error message however, I suspect that the immediate cause of your problems is that the vector points has size zero and so end=points[0][1] is an out of bounds vector access.
Related
Currently I am doing a work related to polygons. Polygon can be described as several vertices.
struct Polygon{
vector<Point2D> vertex;
Color color;
};
Now, I have some polygons already vector<Polygon> polygons
and a method can tell me that a point is inside which polygon
Polygon queryPolygon(Point2D point);
I need to set the color of the returned polygon.
My first question is how to know whether the returned polygon is inside vector<Polygon> polygons, the one I already have.
My first idea is to use unordered_set and compare (vertex.begin(), vertex.end()). I don't know whether there is any better idea.
Another question is some polygon might contain the same edge. How to design the data structure so that I can know the polygons that contains same edge like
vector<Polygon> queryPolygonWithSameEdge(Point2D edgeStart, Point2D edgeEnd);
of course brute-force is one way, but is there any better ideas?
Thanks.
First question
There are some unclear aspects about this first question (see my comments). I'll nevertheless answer, assuming that you want just to compare an arbitrary polygon returned by the query with known polygons stored in your vector, with something like:
auto f = find_if (v.begin(), v.end(), [&p](const auto &x) { return compare1(x.vertex, p.vertex); });
if (f!=v.end()) {
cout << "Found at "<< f-v.begin() <<endl;
}
else cout << "Not found";
Comparing polygons (level 1)
The first level would be to compare point by point. The problem, is that the ordering of points does matter, because with exactly the same points, you can draw a pentagon or a pentagram, just depending on the order chosen and whether or not you accept self-intersecting polygons.
For simply comparing if the vertexes in the two vectors are the same:
bool compare1(const vector<Point2D> &x, const vector<Point2D> &y ) {
return x==y;
}
Unfortunately, this will not work if you have two identical polygones, that are just represented using a different starting point.
Comparing polygons (level 2)
Here we take care of a potential different starting point. So the first thing is to find the offset of the first point of the fist polygon in the second polygon, and perform the comparison by taking care of the offset. If the point is not found in the seond polygon, they are not the same:
bool compare2(const vector<Point2D> &x, const vector<Point2D> &y ) {
if (x.size() != y.size()) // if different size it's not the same
return false;
auto offset = find (y.cbegin(), y.cend(), x[0]); // asumes at least 1 point
if (offset==y.cend())
return false;
return equal(offset, y.cend(), x.cbegin())
&& equal(y.cbegin(), offset, x.cbegin()+(y.cend()-offset));
}
Comparing polygons (level 3)
Now, it's also possible that the points are the same, but the first polygon goes clockwise and the second anticlockwise. So we need to check in both direction:
bool compare3(const vector<Point2D> &x, const vector<Point2D> &y ) {
if (x.size() != y.size())
return false;
auto offset = find (y.cbegin(), y.cend(), x[0]); // asumes at least 1 point
if (offset==y.cend()) // no point in commont
return false;
else if (equal(offset, y.cend(), x.cbegin())
&& equal(y.cbegin(), offset, x.cbegin()+(y.cend()-offset)))
return true;
// not equal. And in reverse order ?
auto roffset = make_reverse_iterator(offset+1);
return equal(roffset, y.crend(), x.cbegin())
&& equal(y.crbegin(), roffset, x.cbegin()+(y.crend()-roffset));
}
Here you have an online demo
Comparing polygons (level 4)
Now it is not excluded that two consecutive edges are perfectly aligned. So it is possible that a polygon has an additional point which is not relevant for the comparison.
I let you as exercise the handling for this case. But the most natural place to process this special case is when you populate your polygon.
Second question
To fin the common edges, the easiest way would IMHO be to add the edges to a map, being understood that you would normalize them to ensure that the points are always in the same order.
You could associate to the edge anything you want, for example: a count, a color, or a container with a pointer to the owning polygon.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 6 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
I'm getting a 'vector subscript out of range' error. I know this is caused by an indexing issue where the index is larger than the maximum size of the array/collection. However, I can't figure out why it's getting to that stage, as I am only ever incrementing the value by one, once in the entire project, and if it becomes larger than the size of the array, I reset it to 0. This is in regards to the frames of an animation in SDL. The index variable in question is m_currentFrame.
Here is the 'Process' method for the animated sprite, this is the only place in the entire project that calls 'm_currentFrame++', I did a ctrl+f search for it:
void
AnimatedSprite::Process(float deltaTime) {
// If not paused...
if (!m_paused){
// Count the time elapsed.
m_timeElapsed += deltaTime;
// If the time elapsed is greater than the frame speed.
if (m_timeElapsed > (float) m_frameSpeed){
// Move to the next frame.
m_currentFrame++;
// Reset the time elapsed counter.
m_timeElapsed = 0.0f;
// If the current frame is greater than the number
// of frame in this animation...
if (m_currentFrame > frameCoordinates.size()){
// Reset to the first frame.
m_currentFrame = 0;
// Stop the animation if it is not looping...
if (!m_loop) {
m_paused = true;
}
}
}
}
}
Here is the method (AnimatedSprite::Draw()), that is throwing the error:
void
AnimatedSprite::Draw(BackBuffer& backbuffer) {
// frame width
int frameWidth = m_frameWidth;
backbuffer.DrawAnimatedSprite(*this, frameCoordinates[m_currentFrame], m_frameWidth, m_frameHeight, this->GetTexture());
}
Here is a screenshot of the exact error:
error
if (m_currentFrame > frameCoordinates.size()){
// Reset to the first frame.
m_currentFrame = 0;
You already need to reset when m_currentFrame == frameCoordinates.size(), because the highest index of an array is its size minus one (counting begins at 0).
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am working on a C++ program which should transfer a 2D image of a flame's intensity into a 3D model. The program is mainly working with multiple matrix-operations which I all realised using pointers (I know, I could use vectors though).
After the Input of the textfile, the mirroring and smoothing of the data values, there comes a correction calculation for each line of the image. At the beginning of the function for this calculation, the program stops on a random position but in the for-loop declaring the y_values-vector.
Here is the code-fragment:
void CorrectionCalculation(Matrix Matrix_To_Calculate, int n_values, int polynomial_degree, int n_rows)
{
for (int h = 0; h < n_rows; h++)
{
//Initialising and declaration of the y_values-vector, which is the copy of each matrix-line. This line is used for the correction-calculation.
double* y_values = new double(n_values);
for (int i = 0; i < n_values; i++)
{
y_values[i] = Matrix_To_Calculate[h][i];
}
//Initialisiing and declaration of the x-values (from 0 to Spiegelachse with stepwidth 1, because of the single Pixels)
double* x_values = new double(n_values);
for (int i = 0; i < n_values; i++)
{
x_values[i] = i;
}
When calculating a single line, the program worked fine. But when I added some code to calculate the whole image, the program stops.
You're not allocating an array of values, but a single element.
Instead of:
double* y_values = new double(n_values);
// ...
double* x_values = new double(n_values);
Change it to
double* y_values = new double[n_values];
//...
double* x_values = new double[n_values];
You should use a vector of doubles rather than array new. That way the memory will be automatically deleted when its no longer needed. E.g.:
#include <vector>
std::vector<double> y_values(y_values);
You're also hiding variables by using variable names the same as the parameters. This can lead to confusion and subtle bugs in code where you're not quite sure which variable is being changed.
I'm currently working on a hobby project in which I have several thousand stars in a 2D fictional universe. I need to render these stars to the screen, but clearly I don't want to have to operate on all of them -- only the ones that are visible at any given time.
For proof of concept, I wrote a brute force algorithm that would look at every star and test its coordinates against the bounds of the player's screen:
for (const std::shared_ptr<Star>& star : stars_) {
if (moved_)
star->MoveStar(starfield_offset_, level_);
position = star->position();
if (position.x >= bounds_[0] &&
position.x <= bounds_[1] &&
position.y >= bounds_[2] &&
position.y <= bounds_[3])
target.draw(*star);
}
While this clunky method does, indeed, draw only the visible stars to the screen, it clearly operates in linear time. Since stars are only part of the background and, frankly, aren't the most important thing for the processor to be spending time filtering through, I'd like to devise a faster algorithm to reduce some of the load.
So, my current train of thought is along the lines of using binary search to find the relevant stars. For this, I would clearly need to sort my data. However, I wasn't really sure how I could go about sorting my coordinate data -- I couldn't think of any absolute ordering that would allow me to properly sort my data in ascending order (with regards to both x and y coordinates).
So, I implemented two new containers -- one for the data sorted by x coordinate, and the other by y coordinate. My original thought was to take the intersection of these two sorted sets and draw the resulting stars to screen (stars whose x and y coordinates lie within the screen bounds):
struct SortedStars {
std::vector<std::shared_ptr<Star>>::iterator begin, end;
std::vector<std::shared_ptr<Star>> stars;
} stars_x_, stars_y_;
I then sorted these containers:
// comparison objects
static struct SortX {
bool operator() (const std::shared_ptr<Star>& first, const std::shared_ptr<Star>& second)
{ return (first->position().x < second->position().x); }
bool operator() (const std::shared_ptr<Star>& first, const float val)
{ return (first->position().x < val); }
bool operator() (const float val, const std::shared_ptr<Star>& second)
{ return (val < second->position().x); }
} sort_x;
static struct SortY {
bool operator() (const std::shared_ptr<Star>& first, const std::shared_ptr<Star>& second)
{ return (first->position().y < second->position().y); }
bool operator() (const std::shared_ptr<Star>& first, const float val)
{ return (first->position().y < val); }
bool operator() (const float val, const std::shared_ptr<Star>& second)
{ return (val < second->position().y); }
} sort_y;
void Starfield::Sort() {
// clone original data (shared pointers)
stars_x_.stars = stars_;
stars_y_.stars = stars_;
// sort as needed
std::sort(stars_x_.stars.begin(), stars_x_.stars.end(), sort_x);
std::sort(stars_y_.stars.begin(), stars_y_.stars.end(), sort_y);
// set iterators to the outermost visible stars (defined by screen bounds)
// these are updated every time the screen is moved
stars_x_.begin = std::lower_bound(stars_x_.stars.begin(), stars_x_.stars.end(), bounds_[0], sort_x);
stars_x_.end = std::upper_bound(stars_x_.stars.begin(), stars_x_.stars.end(), bounds_[1], sort_x);
stars_y_.begin = std::lower_bound(stars_y_.stars.begin(), stars_y_.stars.end(), bounds_[2], sort_y);
stars_y_.end = std::upper_bound(stars_y_.stars.begin(), stars_y_.stars.end(), bounds_[3], sort_y);
return;
}
Unfortunately, I cannot seem to either come up with an appropriate comparison function for std::set_intersection or a method through which I could manually compare coordinates using my iterators.
Could you guys point me in the right direction? Feedback on my methodology or implementation is very welcome.
Thanks for your time!
There are a variety of spatial acceleration data structures that help to answer questions of 'what points are in this region'. Quadtrees are a popular solution for 2D but may be overkill for your problem. Probably the simplest approach is to have a 2D grid with points (stars) bucketed by the grid square they fall into. You then check to see which grid squares your view window overlaps and only need to look at the stars in the buckets for those squares. If you make your grid squares a bit larger than your view window size you'll only ever have to check a maximum of four buckets.
If you can zoom in and out a more complicated structure like a Quadtree might be appropriate.
I use real star data for rendering (psychosomatic style) for years and have no speed problems without any visibility ordering/selecting under OpenGL (VBO)
I usually used BSC star catalog in the past
stars up to +6.5mag
9110 stars
few years back I convert my engines to hipparcos catalog
118322 stars
3D coordinates
So unless you use too much stars it should be faster to just render them all
- How many stars are you rendering?
- How are you stars rendered? (I use blended Quad per star)
What platform/setup ...
- this worked well even on my old setup GeForce 4000 Ti, 1.3GHz single core AMD
- also in stereo 3D
what is your desired FPS ? ... I am fine with 30fps for my simulations
If you have similar values and low speed may be there is something wrong with your rendering code (not with the amount of data)...
PS.
if you have a big space to cover you can select bright stars to viewer only
after each hyperspace jump or what ever
based on relative magnitude and distance
also you use too much ifs for star selection
they are sometimes slower then the rendering
try just dot product of viewing direction and star direction vectors instead
and test the sign only (do not see what is behind)
of course if you use quads then CULL_FACE make it for you
Also i see you are calling draw for each star
that is heap trashing
try to avoid calling functions when you can
it will boost the speed a lot !!!
for example you can add a flag to each star if it should be rendered or not
and then render them with single for and no sub-calls to render function
You can try spatial R-tree which is now part of Boost Geometry library.
The application could work as follows:
You add your star's coordinate to the tree in some "absolute" coordinate system. If your stars have different sizes you probably want to add not a point but a bounding box of each star.
#include <boost/geometry/index/rtree.hpp>
#include <boost/geometry/geometries/box.hpp>
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
typedef bg::model::point<float, 2, bg::cs::cartesian> point;
typedef bg::model::box<point> box;
typedef std::pair<box, Star*> value; //here "second" can optionally give the star index in star's storage
bgi::rtree<value> rtree;
As you build your universe, you populate the rtree:
for (auto star: stars)
{
box b(star->position(), star->position()));
bg::expand(b, point(star->radius(), star->radius());
// insert new value
rtree.insert(std::make_pair(b, star));
}
When you need to render them, you compute your screen window into "absolute" coord system and query the tree about stars which overlap your window:
box query_box(point(0, 0), point(5, 5));
std::vector<value> result_s;
rtree.query(bgi::intersects(query_box), std::back_inserter(result_s));
Here result_s will list the relevant stars and their bounding boxes.
Good luck!
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions must demonstrate a minimal understanding of the problem being solved. Tell us what you've tried to do, why it didn't work, and how it should work. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Guys I a new programmer in C++, please can you help me out in writing a program for drawing a blue colored rectangle in Visual C++ in a bitmap 24bit colored image without using OpenCV.
Also in VS C++ I'm not able to get a header graphics.h instead what shud i use.
I have to draw a rectangle in the image not the line
Here is my code in VS-C++ which only shows a black line at the bottom:
void copy_Header(FILE *,FILE *);
void main()
{
FILE *src; int offset; int width, height;
fopen_s(&src,"jaguar.bmp","rb");
FILE *dest;
fopen_s(&dest,"rect_image.bmp","wb");
fseek(src,10,SEEK_SET);
fread(&offset,4,1,src);
fseek(src,18,SEEK_SET);
fread(&width,4,1,src);
fseek(src,22,SEEK_SET);
fread(&height,4,1,src);
copy_Header(src,dest);
fseek(src,offset,SEEK_SET);
fseek(dest,offset,SEEK_SET);
unsigned char x=(unsigned char)fgetc(src);
double r,g,b,z[3];
int i;
unsigned char ch[3];
b=ch[0]=fgetc(src);
g=ch[1]=fgetc(src);
r=ch[2]=fgetc(src);
for (int j=0;j<4;j++)
{
for(; offset<width; offset++)
{
z[0]=b;
z[1]=0;
z[2]=0;
fputc(z[0],dest);
fputc(z[1],dest);
fputc(z[2],dest);
}
}
fseek(src,4096,SEEK_SET);
fseek(dest,4096,SEEK_SET);
unsigned char y= (unsigned char)fgetc(src);
while(!feof(src))
{
fputc(y,dest);
y=(unsigned char)fgetc(src);
}
fclose(src);
fclose(dest);
puts("Image Copied");
_getch();
}
void copy_Header(FILE *srcImage,FILE *dstImage)
{
unsigned char *ptrc= (unsigned char *)malloc(54*sizeof(char));
fseek(srcImage,0,SEEK_SET);
fseek(dstImage,0,SEEK_SET);
fread(ptrc,54,1,srcImage);
fwrite(ptrc,54,1,dstImage);
}
Thanx in advance.
image size is of 1024 by 1024 and is 24 bit bitmap file.
Let's break the problem.
First problem: how do you relate a pixel coordinate to its position in a file?
In other words, given a RGB pixel with coordinates (x,y), where is it located on the file?
Let's consider that it has WIDTH width and HEIGHT height. Since it has 3 channels - Red, Green, and Blue - and considering each channel has 1 byte, each pixel will have 3 bytes in size. A BMP file is just a matrix of pixels, organized line by line, so each line will have then 3*WIDTH bytes.
The x coordinate will then tell how many lines will be skipped, and y will point to the pixel in the current line. In other words:
seek_position= x*(3*WIDTH) + 3*y
With this relation, you can now write a function like
int mat2seek(int x,int y){
//converts a xy coordinate system to seek position
return x*(3*WIDTH) + 3*y + BMP_HEADER_SIZE;
}
where BMP_HEADER_SIZE is self explaining
Second problem: now that you know how to convert a (x,y) coordinate system to seek system, what is the algorithm of drawing a rectangle?
Such algorithm is a lot easier to make in (x,y) coordinate than seek coordinates:
for (int x = xini; x< xend; x++)
for (int y=yini; y<yend; y++){
int seek=mat2seek(x,y);
//do the magic...
}