Ejemplo n.º 1
0
TEST(MatrixTest, rotate) {
	RotationMatrix m(90);
	DPair p = m*DPair(2,0);
	EXPECT_NEAR(p.x(), 0, 0.0000000001);
	EXPECT_NEAR(p.y(), 2, 0.0000000001);

	p = m*p;
	EXPECT_NEAR(p.x(), -2, 0.0000000001);
	EXPECT_NEAR(p.y(), 0, 0.0000000001);
}
Ejemplo n.º 2
0
TEST(MatrixTest, scale) {
	ScalingMatrix m(2,2);
	DPair p = m*DPair(3,3);
	EXPECT_DOUBLE_EQ(p.x(), 6);
	EXPECT_DOUBLE_EQ(p.y(), 6);

	m = ScalingMatrix(-2,-2);
	p = m*DPair(3,3);
	EXPECT_DOUBLE_EQ(p.x(), -6);
	EXPECT_DOUBLE_EQ(p.y(), -6);
}
Ejemplo n.º 3
0
DPair Matrix::operator * (const DPair &p) const {
    double pp[] = {p.x(), p.y(), 1};
    double ret[]= {0, 0};
    for (int i=0; i < 2; i++)
        for (int j=0; j < 3; j++)
            ret[i] += _values[i][j] * pp[j];
    return DPair(ret[0], ret[1]);
}
Ejemplo n.º 4
0
TEST(PairTest, constructor) {
	DPair p(-1.5, 2);
	ASSERT_EQ(p.x(), -1.5);
	ASSERT_EQ(p.y(), 2);
	DPair q = p;
	ASSERT_EQ(q.x(), -1.5);
	ASSERT_EQ(q.y(), 2);
}
Ejemplo n.º 5
0
void BoundingBox::transform (const Matrix &tm) {
	if (!_locked) {
		DPair ul = tm * DPair(_lrx, _lry);
		DPair lr = tm * DPair(_ulx, _uly);
		DPair ll = tm * DPair(_ulx, _lry);
		DPair ur = tm * DPair(_lrx, _uly);
		_ulx = min(min(ul.x(), lr.x()), min(ur.x(), ll.x()));
		_uly = min(min(ul.y(), lr.y()), min(ur.y(), ll.y()));
		_lrx = max(max(ul.x(), lr.x()), max(ur.x(), ll.x()));
		_lry = max(max(ul.y(), lr.y()), max(ur.y(), ll.y()));
	}
}
Ejemplo n.º 6
0
/** Creates the SVG element that will a the line.
 * @param[in] p1 first endpoint in PS point units
 * @param[in] p2 second endpoint in PS point units
 * @param[in] c1 cut method of first endpoint ('h', 'v' or 'p')
 * @param[in] c2 cut method of second endpoint ('h', 'v' or 'p')
 * @param[in] lw line width in PS point units
 * @param[in] actions object providing the actions that can be performed by the SpecialHandler */
static void create_line (const DPair &p1, const DPair &p2, char c1, char c2, double lw, SpecialActions &actions) {
	unique_ptr<XMLElementNode> node;
	DPair dir = p2-p1;
	if (dir.x() == 0 || dir.y() == 0 || (c1 == 'p' && c2 == 'p')) {
		// draw regular line
		node = util::make_unique<XMLElementNode>("line");
		node->addAttribute("x1", p1.x());
		node->addAttribute("y1", p1.y());
		node->addAttribute("x2", p2.x());
		node->addAttribute("y2", p2.y());
		node->addAttribute("stroke-width", lw);
		node->addAttribute("stroke", actions.getColor().svgColorString());
		// update bounding box
		DPair cv = cut_vector('p', dir, lw);
		actions.embed(p1+cv);
		actions.embed(p1-cv);
		actions.embed(p2+cv);
		actions.embed(p2-cv);
	}
	else {
		// draw polygon
		DPair cv1 = cut_vector(c1, dir, lw);
		DPair cv2 = cut_vector(c2, dir, lw);
		DPair q11 = p1+cv1, q12 = p1-cv1;
		DPair q21 = p2+cv2, q22 = p2-cv2;
		ostringstream oss;
		oss << XMLString(q11.x()) << ',' << XMLString(q11.y()) << ' '
			 << XMLString(q12.x()) << ',' << XMLString(q12.y()) << ' '
			 << XMLString(q22.x()) << ',' << XMLString(q22.y()) << ' '
			 << XMLString(q21.x()) << ',' << XMLString(q21.y());
		node = util::make_unique<XMLElementNode>("polygon");
		node->addAttribute("points", oss.str());
		if (actions.getColor() != Color::BLACK)
			node->addAttribute("fill", actions.getColor().svgColorString());
		// update bounding box
		actions.embed(q11);
		actions.embed(q12);
		actions.embed(q21);
		actions.embed(q22);
	}
	actions.appendToPage(std::move(node));
}
Ejemplo n.º 7
0
/** Computes the "cut vector" that is used to compute the line shape.
 *  Because each line has a width > 0 the actual shape of the line is a tetragon.
 *  The 4 vertices can be influenced by the cut parameter c that specifies
 *  a horizontal, vertical or orthogonal cut of a line end. Depending on c and the
 *  line's slope a cut vector v can be computed that, relatively to endpoint p, denotes
 *  the 2 vertices of that line end: v1=p+v and v2=p-v.
 *  @param[in] cuttype character identifying the cut direction ('h', 'v' or 'p')
 *  @param[in] linedir direction vector of line to be drawn
 *  @param[in] lw width of line to be drawn
 *  @return the "cut vector" */
static DPair cut_vector (char cuttype, const DPair &linedir, double linewidth) {
	DPair cut;
	switch (cuttype) {
		case 'v':  // vertical
			if (linedir.x() != 0) {
				double slope = linedir.y()/linedir.x();
				double h = sqrt(linewidth*linewidth*(1+slope*slope));
				cut.y(h/2);
			}
			break;
		case 'h':  // horizontal
			if (linedir.y() != 0) {
				double slope = linedir.x()/linedir.y();
				double h = sqrt(linewidth*linewidth*(1+slope*slope));
				double sgn = slope < 0 ? 1.0 : -1.0;
				cut.x(h*sgn/2);
			}
			break;
		default: // c == 'p': perpendicular to the line vector
			if (linedir.x() != 0 && linedir.y() != 0)
				return linedir.ortho()/linedir.length() * (linewidth/2);
	}
	return cut;
}
Ejemplo n.º 8
0
BoundingBox::BoundingBox (const DPair &p1, const DPair &p2)
	: _ulx(min(p1.x(), p2.x())), _uly(min(p1.y(), p2.y())),
	  _lrx(max(p1.x(), p2.x())), _lry(max(p1.y(), p2.y())),
	  _valid(true), _locked(false)
{
}
Ejemplo n.º 9
0
/** Embeds a virtual circle into the box and enlarges it accordingly.
 * @param[in] c center of the circle
 * @param[in] r radius of the circle */
void BoundingBox::embed (const DPair &c, double r) {
	embed(BoundingBox(c.x()-r, c.y()-r, c.x()+r, c.y()+r));
}