#include <cstdlib> #include <iostream> #include <math.h> #include <vector> #incl
ID: 3598493 • Letter: #
Question
#include <cstdlib>
#include <iostream>
#include <math.h>
#include <vector>
#include <utility>
#include <fstream>
using namespace std;
typedef unsigned int byte;
struct RGBColor
{
byte red;
byte green;
byte blue;
RGBColor(byte r = 0, byte g = 0, byte b = 0):red(r), green(g), blue(b){}
friend bool operator==(const RGBColor& c1, const RGBColor& c2)
{
return (c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue);
}
friend bool operator!=(const RGBColor& c1, const RGBColor& c2)
{
return !(c1 == c2);
}
};
typedef unsigned int uint;
struct Point
{
int x;
int y;
Point(int _x = 0, int _y = 0):x(_x), y(_y){}
friend bool operator==(const Point& p1, const Point& p2)
{
return (p1.x == p2.x && p1.y == p2.y);
}
friend bool operator!=(const Point& p1, const Point& p2)
{
return !(p1 == p2);
}
friend void swap(Point& p1, Point& p2)
{
Point temp = p2;
p2 = p1;
p1 = temp;
}
};
struct Point3D
{
int x;
int y;
int z;
friend Point3D operator-(const Point3D& p1, const Point3D& p2)
{
Point3D dif_p;
dif_p.x = p1.x - p2.x;
dif_p.y = p1.y - p2.y;
dif_p.z = p1.z - p2.z;
return dif_p;
}
friend Point3D operator*(const Point3D& p1, const Point3D& p2)
{
return Point3D{p1.x*p2.x, p1.y*p2.y, p1.z*p2.z};
}
};
struct Polygon
{
Point3D p[4];
RGBColor col;
};
struct Sphere
{
Point3D center;
int radius;
RGBColor col;
};
struct Vector
{
double _1;
double _2;
double _3;
};
struct VRPS
{
Vector u;
Vector v;
Vector n;
};
class PPMImage
{
private:
RGBColor** pixmap;
size_t heigth;
size_t width;
public:
PPMImage(size_t h, size_t w, RGBColor background);
~PPMImage();
void drawLine(Point start, Point end, RGBColor col);
void createFile(const string& _filename);
void drawCircle(Point center, int radius, RGBColor col);
void fill(Point start, RGBColor fillCol, RGBColor back);
void drawPolygon(Point *points, int size, RGBColor col);
PPMImage(const PPMImage&) = delete;
PPMImage& operator=(const PPMImage&) = delete;
};
PPMImage::PPMImage(size_t h, size_t w, RGBColor background):width(w), heigth(h)
{
pixmap = new RGBColor*[heigth];
for(size_t i = 0; i < heigth; i++)
pixmap[i] = new RGBColor[width];
for(size_t i = 0; i < heigth; i++)
for(size_t j = 0; j < width; j++)
pixmap[i][j] = background;
}
PPMImage::~PPMImage()
{
for(size_t i = 0; i < heigth; i++)
delete [] pixmap[i];
delete [] pixmap;
}
void PPMImage::drawLine(Point p1, Point p2, RGBColor color)
{
double dx = abs(p1.x - p2.x);
double dy = abs(p1.y - p2.y),
k = 1,
b = p1.y - p1.x * k;
if (p1.x != p2.x) {
int _dx = p1.x < p2.x ? 1 : -1,
_dy = p1.y < p2.y ? 1 : -1;
if (dx > dy)
{
double step = dy/dx;
double y = p1.y;
if(p1.y < p2.y)
step = -step;
for (size_t x = p1.x; x != p2.x; x += _dx)
{
y += step;
if(y < 0)
break;
pixmap[(int)y][x] = color;
}
}
else
{
double step = dx/dy;
if(p1.x > p2.x)
step = -step;
double x = p1.x;
for (size_t y = p1.y; y != p2.y; y += _dy) {
x += step;
pixmap[y][(int)x] = color;
}
}
pixmap[p2.y][p2.x] = color;
}
else
{
if (p1.y > p2.y)
swap(p1,p2);
int x = p1.x;
for (size_t y = p1.y; y <= p2.y; ++y) {
pixmap[y][x] = color;
}
}
}
void PPMImage::createFile(const string &_filename)
{
ofstream out(_filename);
if(!out.is_open()){
cout << "ERROR: can't create file ";
return;
}
out << "P3" << " ";
out << width << " " << heigth << ' ';
out << "255" << ' ';
for(size_t i = heigth-1; i >= 0; i--)
for(size_t j = 0; j < width; j++)
{
out << (uint)pixmap[i][j].red << ' ';
out << (uint)pixmap[i][j].green << ' ';
out << (uint)pixmap[i][j].blue << ' ';
}
}
void PPMImage::drawCircle(Point center, int radius, RGBColor col)
{
int x = 0, y = -radius;
// previous `x` and `y`
int _x = x, _y = y;
// compute r^2 only once
int rr = radius * radius;
while (_y < radius) {
// compute next `x`
y = _y + 1, x = round(sqrt(rr-y*y));
// move `x` and `y` by center coordinates
x += center.x;
y += center.y;
_x += center.x;
_y += center.y;
// draw compute `x`
pixmap[y][x] = col;
// draw reflected `x`
pixmap[y][2 * center.x - x] = col;
// connect previous points with current ones
drawLine(Point(_x, _y), Point(x, y), col);
drawLine(Point(2 * center.x - x, y), Point(2 * center.x - _x, _y), col);
// move previous
_x = x - center.x, _y = y - center.y;
}
}
void PPMImage::fill(Point start, RGBColor fillcol, RGBColor col) {
if (fillcol == col){
return;
}
int x = start.x, y = start.y;
if (x < 0 || x >= width || y < 0 || y >= heigth)
return;
if (pixmap[y][x] != col)
return;
pixmap[y][x] = fillcol;
fill(Point(x + 1, y), fillcol, col);
fill(Point(x - 1, y), fillcol, col);
fill(Point(x, y + 1), fillcol, col);
fill(Point(x, y - 1), fillcol, col);
}
void PPMImage::drawPolygon(Point *points, int size, RGBColor col)
{
for (int i = 0; i < size - 1; ++i) {
drawLine(points[i], points[i+1], col);
}
drawLine(points[size-1], points[0], col);
}
VRPS view_algorithm(double a, double b);
Point3D view_alignment_algo(Point3D p,VRPS vrps, Point3D p3d, Point3D cop);
void scale3D(Point3D &p, int sf);
bool surfaceAlgo(Point3D* p, Point3D pointIS);
pair<bool, Point3D> sphereIntersection(Point3D cop, Point3D pix, Sphere sph);
Point* dotFind(Point3D cop,Point3D pix ,Polygon pol);
Point convertTo(Point3D, char type);
int main()
{
double a = 0, b = 0, sf = 2;
Point3D vpr = {50,50,120};
Point3D cop = {0,0, 50};
Point3D topCorner = {-30, 30, 0};
Point3D bottonCorner = {30, -30, 0};
Point3D pix = {200,200,50};
RGBColor col = {245,245,245};
PPMImage img(1280, 720, col);
// initialize all polygons and spheres
Polygon polygons[6];
polygons[0].p[0] = Point3D{0,0,0};
polygons[0].p[1] = Point3D{100,0,0};
polygons[0].p[2] = Point3D{100,0,100};
polygons[0].p[3] = Point3D{0,0,100};
polygons[0].col = RGBColor{0,0,0};
polygons[1].p[0] = Point3D{0,0,0};
polygons[1].p[1] = Point3D{0,100,0};
polygons[1].p[2] = Point3D{0,100,100};
polygons[1].p[3] = Point3D{0,0,100};
polygons[1].col = RGBColor{0,0,0};
polygons[2].p[0] = Point3D{0,0,0};
polygons[2].p[1] = Point3D{0,100,0};
polygons[2].p[2] = Point3D{100,100,0};
polygons[2].p[3] = Point3D{100,0,0};
polygons[2].col = RGBColor{255,255,255};
polygons[3].p[0] = Point3D{10,30,85};
polygons[3].p[1] = Point3D{70,30,85};
polygons[3].p[2] = Point3D{70,30,5};
polygons[3].p[3] = Point3D{10,30,5};
polygons[3].col = RGBColor{255,255,0};
polygons[4].p[0] = Point3D{60,0,80};
polygons[4].p[1] = Point3D{60,30,80};
polygons[4].p[2] = Point3D{60,30,10};
polygons[4].p[3] = Point3D{60,0,10};
polygons[4].col = RGBColor{255,255,0};
polygons[5].p[0] = Point3D{10,30,85};
polygons[5].p[1] = Point3D{70,30,85};
polygons[5].p[2] = Point3D{70,30,5};
polygons[5].p[3] = Point3D{10,30,5};
polygons[5].col = RGBColor{255,255,0};
// initialize the sphere
Sphere sphere[2];
sphere[0].center = {50,80,50};
sphere[0].radius = 20;
sphere[0].col = {255,0,0};
sphere[1].center = {80,50,70};
sphere[1].radius = 10;
sphere[1].col = {0,255,0};
/// initializition is end/////////////////////////////
VRPS view = view_algorithm(a, b); // get view using 3d view algorithm
// apply 3d view alignment algorithm and scaled 3D for every polygon and spheres
for(int i = 0; i < 6; i++){
for(int j = 0; j < 4; j++){
// cout << "Point 3d: " << polygons[i].p[j].x << " "<<polygons[i].p[j].y <<" "<<polygons[i].p[j].z << endl;
polygons[i].p[j] = view_alignment_algo(polygons[i].p[j], view, vpr, cop);
// cout << "Point 3d(after view): " << polygons[i].p[j].x << " "<<polygons[i].p[j].y <<" "<<polygons[i].p[j].z << endl;
scale3D(polygons[i].p[j], sf);
// cout << "Point 3d(after scale): " << polygons[i].p[j].x << " "<<polygons[i].p[j].y <<" "<<polygons[i].p[j].z << endl;
}
Point* d4 = dotFind(cop, pix, polygons[i]);
for(int i = 0; i < 4; i++){
cout << "X: " << d4[i].x << " " << d4[i].y << endl;
d4[i].x +=340;
d4[i].y +=340;
}
img.drawPolygon(d4, 4, polygons[i].col);
img.fill(d4[0], polygons[i].col, col);
delete d4;
}
for(int i = 0; i < 2; i ++)
{
sphere[i].center = view_alignment_algo(sphere[i].center, view, vpr, cop);
sphere[i].radius*=sf;
scale3D(sphere[i].center, sf);
//pair<bool, Point3D> p = sphereIntersection(cop, pix, sphere[i]);
//cout << p.second.x << " " << p.second.y << endl;
img.drawCircle(Point{abs(sphere[i].center.x), abs(sphere[i].center.y)}, sphere[i].radius, sphere[i].col);
}
scale3D(topCorner, sf);
scale3D(bottonCorner, sf);
img.createFile("house.ppm");
/*
Point3D* p = new Point3D[3];
p[0] = Point3D{50,50,70};
p[1] = Point3D{30,40,50};
p[2] = Point3D{35,40,70};
Point3D vrp = {20,20,75};
Point3D cop = {50,50,200};
double _a = 45;
double _b = 90;
Point3D pix = {50,50,150};
VRPS vprs;
vprs.u = {0.707, 0.707, 0};
vprs.v = {0,0,1};
vprs.n = {0.707, -0.707, 0};
Sphere sp;
sp.center = {50,50,70};
sp.radius = 20;
pair<bool, Point3D> pp = sphereIntersection(cop, pix, sp );
cout << pp.second.x << " " << pp.second.y << " " << pp.second.z << endl;
*/
return 0;
}
// work correct
Point* dotFind(Point3D cop, Point3D pix ,Polygon pol)
{
char type;
Point3D v12 = pol.p[1] - pol.p[0];
Point3D v13 = pol.p[2] - pol.p[0];
double A = v13.y * v12.z - v13.z * v12.y;
double B = v13.z * v12.x - v13.x * v12.z;
double C = v13.x * v12.y - v13.y * v12.x;
//cout << "A: " << A << " B: "<< B << " C: " << C << endl;
double D = -(A * pol.p[0].x + B * pol.p[0].y + C * pol.p[0].z);
//cout << D << endl;
if((abs((int)A) > abs((int)B)) && (abs((int)A) > abs((int)C)))
type = 'A';
if(abs((int)B) > abs((int)A) && abs((int)B) > abs((int)C))
type = 'B';
if(abs((int)C) > abs((int)B) && abs((int)C) > abs((int)A))
type = 'C';
double t = -( A*cop.x + B*cop.y + C*cop.z + D)/(A*(pix.x - cop.x) + B*(pix.y - cop.y) + C*(pix.z - cop.z));
Point* arr = new Point[4];
for(int i = 0; i < 4; i++)
arr[i] = convertTo(pol.p[i], type);
return arr;
}
// work correct
/*bool surfaceAlgo(Polygon pol, Point3D pointIS, Point3D cop)
{
Point* p = dotFind(cop, pointIS, pol);
Point arr[3];
for(int i = 0; i < 4; i++)
arr[i] = convertTo(p[i], type);
Point _zero = convertTo(pointIS, type);
double t_j = (_zero.y - arr[0].y)/(arr[1].y - arr[0].y);
double t_i = (_zero.x - arr[0].x)/(arr[1].x - arr[0].x);
if(t_j > 1 || t_j < 0 ) return false;
if(t_i > 1 || t_i < 0 ) return false;
//int i = arr[0].x + t_i * (arr[1].x - arr[0].x);
//int j = arr[0].y + t_j * (arr[1].y - arr[0].y);
return true;
}
*/
//correct
void scale3D(Point3D& p, int sf)
{
p.x *= sf;
p.y *= sf;
p.z *= sf;
}
// work correct
/////////////////////
/// rief sphereIntersection
/// param cop
/// param pix
/// param sph
/// eturn bool - is intersection
/// point3d - intersection point
///
///
pair<bool, Point3D> sphereIntersection(Point3D cop, Point3D pix, Sphere sph)
{
double A = (pix.x - cop.x)*(pix.x - cop.x) + (pix.y - cop.y)*(pix.y - cop.y) + (pix.z - cop.z)*(pix.z - cop.z);
double B = 2*((pix.x - cop.x) * (cop.x - sph.center.x) + (pix.y - cop.y) * (cop.y - sph.center.y) +
(pix.z - cop.z) * (cop.z - sph.center.z));
double C = (cop.x - sph.center.x) * (cop.x - sph.center.x) + (cop.y - sph.center.y) * (cop.y - sph.center.y) + (cop.z - sph.center.z) * (cop.z - sph.center.z) - sph.radius*sph.radius;
// cout << " A: " << A << " B: " << B << " C: " << C << endl;
long double t_1 = (-B + sqrt(abs((int)(B*B - 4 * A * C))))/ (2*A);
// cout << "t_ 1 " << t_1 << endl;
double t_2 = (-B - sqrt(abs((int)(B*B - 4 * A * C))))/ (2*A);
//cout << "t_ 1 " << t_2 << endl;
Point3D p;
p.x = cop.x + t_2*(pix.x - cop.x);
p.y = cop.y + t_2*(pix.y - cop.y);
p.z = cop.z + t_2*(pix.z - cop.z);
if (t_1 != t_2 && t_1 > 0 && t_2 > 0)
{
return make_pair(true, p);
}
return make_pair(false, p);
}
///////////////////////////////////////////////////////////////////////
/// rief view_algorithm
/// param vrp -- (0,0,1)(0,1,0)(1,0,0)
/// param a --
/// param b ---
/// eturn
///
// work correct
VRPS view_algorithm(double a, double b)
{
const double pi = acos(-1);
VRPS vrp;
vrp.u = {1.,0.,0.};
vrp.v = {0.,1.,0.};
vrp.n = {0.,0.,1.};
double a_ = sin(a*pi/180);
double b_ = sin(b*pi/180);
double _b = cos(b*pi/180);
double _a = cos(a*pi/180);
VRPS rb_vpr;
rb_vpr.u._1 = vrp.u._1;
rb_vpr.u._2 = vrp.u._2 * _b - (vrp.u._3*b_);
rb_vpr.u._3 = vrp.u._3 * _b + (vrp.u._2*b_);
rb_vpr.v._1 = vrp.v._1;
rb_vpr.v._2 = vrp.v._2 * _b - (vrp.v._3*b_);
rb_vpr.v._3 = vrp.v._3 * _b + (vrp.v._2*b_);
rb_vpr.n._1 = vrp.n._1;
rb_vpr.n._2 = vrp.n._2 * _b - (vrp.n._3*b_);
rb_vpr.n._3 = vrp.n._3 * _b + (vrp.n._2*b_);
VRPS ra_vpr;
ra_vpr.u._1 = rb_vpr.u._1 * _a + (rb_vpr.u._3*a_);
ra_vpr.u._2 = rb_vpr.u._2;
ra_vpr.u._3 = rb_vpr.u._3 * _a - (rb_vpr.u._1*a_);
ra_vpr.v._1 = rb_vpr.v._1 * _a + (rb_vpr.v._3*a_);
ra_vpr.v._2 = rb_vpr.v._2;
ra_vpr.v._3 = rb_vpr.v._3 * _a - (rb_vpr.v._1*a_);
ra_vpr.n._1 = rb_vpr.n._1 * _a + (rb_vpr.n._3*a_);
ra_vpr.n._2 = rb_vpr.n._2;
ra_vpr.n._3 = rb_vpr.n._3 * _a - (rb_vpr.n._1*a_);
//////////////////////////////////////////////////
return ra_vpr;
}
/*
* vrps - get from view algo
* cop - center of projection
* p -
* vpr -
*/
// work correct
Point3D view_alignment_algo(Point3D p, VRPS vrps, Point3D vpr, Point3D cop)
{
Point3D tp1;
tp1.x = p.x - vpr.x;
tp1.y = p.y - vpr.y;
tp1.z = p.z - vpr.z;
Point3D tp2;
tp2.x = tp1.x * vrps.u._1 + tp1.y * vrps.u._2 + tp1.z * vrps.u._3;
tp2.y = tp1.x * vrps.v._1 + tp1.y * vrps.v._2 + tp1.z * vrps.v._3;
tp2.z = tp1.x * vrps.n._1 + tp1.y * vrps.n._2 + tp1.z * vrps.n._3;
Point3D tp3;
tp3.x = tp2.x - cop.x;
tp3.y = tp2.y - cop.y;
tp3.z = tp2.z - cop.z;
return tp3;
}
// work correct
Point convertTo(Point3D p, char type)
{
Point to;
if(type == 'A'){
to.x = p.y;
to.y = p.z;
}
else if(type == 'B')
{
to.x = p.x;
to.y = p.z;
}
else
{
to.x = p.x;
to.y = p.y;
}
return to;
}
************hi program keeps crashing codeblock c++ - help please graphics c++ ppm
Explanation / Answer
package com.one;
class DList<T> {
private DNode<T> header, trailer;
private int size;
public DList() {
size = 0;
header = new DNode<T>(null, null, null);
trailer = new DNode<T>(null, header, null);
header.setNext(trailer);
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
// give clients access to nodes, but not to the header or trailer
public DNode<T> getFirst() throws Exception {
if (isEmpty())
throw new Exception("Empty");
return header.getNext();
}
public DNode<T> getLast() throws Exception {
if (isEmpty())
throw new Exception("Empty");
return trailer.getPrev();
}
public DNode<T> getNext(DNode<T> v) throws Exception {
DNode<T> ans = v.getNext();
if (ans == null || ans == trailer)
throw new Exception("No such node");
return ans;
}
public DNode<T> getPrev(DNode<T> v) throws Exception {
DNode<T> ans = v.getPrev();
if (ans == null || ans == header)
throw new Exception("No such node");
return ans;
}
// methods to change the list
public void addBefore(T d, DNode<T> v) {
DNode<T> u = v.getPrev();
DNode<T> x = new DNode<T>(d, u, v);
u.setNext(x);
v.setPrev(x);
size++;
}
public void addAfter(T d, DNode<T> v) {
DNode<T> w = v.getNext();
DNode<T> x = new DNode<T>(d, v, w);
v.setNext(x);
w.setPrev(x);
size++;
}
public void addFirst(T d) {
addAfter(d, header);
}
public void addLast(T d) {
addBefore(d, trailer);
}
public T remove(DNode<T> v) throws Exception {
if (v == header || v == trailer)
throw new Exception("Sentinel");
DNode<T> u = v.getPrev();
DNode<T> w = v.getNext();
w.setPrev(u);
u.setNext(w);
size--;
return v.getData();
}
// LinkedList testing methods:
public String toString() {
String ans = "";
DNode<T> n = header;
ans += "(H)<-->";
do {
n = n.getNext();
if (n == trailer)
ans += "(T)";
else
ans += (n.getData() + "<-->");
} while (n != trailer);
return ans;
}
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.