3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // (C) 2010 Underground Software
8 // JLH = James L. Hammons <jlhamm@acm.org>
11 // --- ---------- -----------------------------------------------------------
12 // JLH 05/28/2010 Added this text. :-)
17 #include "rs_constructionline.h"
19 #include "rs_graphicview.h"
20 #include "paintintf.h"
25 RS_Image::RS_Image(RS_EntityContainer * parent, const RS_ImageData & d):
26 RS_AtomicEntity(parent), data(d)
42 RS_Entity * RS_Image::clone()
44 RS_Image * i = new RS_Image(*this);
45 i->setHandle(getHandle());
51 void RS_Image::update()
53 RS_DEBUG->print("RS_Image::update");
56 //QImage image = QImage(data.file);
57 img = QImage(data.file);
60 data.size = Vector(img.width(), img.height());
62 RS_DEBUG->print("RS_Image::update: OK");
65 // number of small images:
66 nx = image.width()/100;
67 ny = image.height()/100;
69 // create small images:
70 img = new QImage*[nx];
73 for (int x = 0; x<nx; ++x) {
74 img[x] = new QImage[ny];
75 for (int y = 0; y<ny; ++y) {
80 w = image.width()%100;
87 h = image.height()%100;
91 RS_PainterQt painter(&pm);
92 painter.drawImage(-x*100, -y*100, image);
93 img[x][y] = pm.convertToImage();
99 void RS_Image::calculateBorders()
102 VectorSolutions sol = getCorners();
104 for(int i=0; i<4; ++i)
106 minV = Vector::minimum(minV, sol.get(i));
107 maxV = Vector::maximum(maxV, sol.get(i));
111 Vector RS_Image::getNearestEndpoint(const Vector & coord, double * dist)
113 VectorSolutions corners = getCorners();
114 return corners.getClosest(coord, dist);
117 Vector RS_Image::getNearestPointOnEntity(const Vector & coord, bool onEntity, double * dist,
123 VectorSolutions corners = getCorners();
124 VectorSolutions points(4);
127 RS_Line(NULL, RS_LineData(corners.get(0), corners.get(1))),
128 RS_Line(NULL, RS_LineData(corners.get(1), corners.get(2))),
129 RS_Line(NULL, RS_LineData(corners.get(2), corners.get(3))),
130 RS_Line(NULL, RS_LineData(corners.get(3), corners.get(0)))
133 for(int i=0; i<4; ++i)
134 points.set(i, l[i].getNearestPointOnEntity(coord, onEntity));
136 return points.getClosest(coord, dist);
139 Vector RS_Image::getNearestCenter(const Vector & coord, double * dist)
141 VectorSolutions points(4);
142 VectorSolutions corners = getCorners();
144 points.set(0, (corners.get(0) + corners.get(1))/2.0);
145 points.set(1, (corners.get(1) + corners.get(2))/2.0);
146 points.set(2, (corners.get(2) + corners.get(3))/2.0);
147 points.set(3, (corners.get(3) + corners.get(0))/2.0);
149 return points.getClosest(coord, dist);
154 Vector RS_Image::getNearestMiddle(const Vector& coord,
156 return getNearestCenter(coord, dist);
161 Vector RS_Image::getNearestDist(double distance,
165 VectorSolutions corners = getCorners();
166 VectorSolutions points(4);
170 RS_Line(NULL, RS_LineData(corners.get(0), corners.get(1))),
171 RS_Line(NULL, RS_LineData(corners.get(1), corners.get(2))),
172 RS_Line(NULL, RS_LineData(corners.get(2), corners.get(3))),
173 RS_Line(NULL, RS_LineData(corners.get(3), corners.get(0)))
176 for (int i=0; i<4; ++i) {
177 points.set(i, l[i].getNearestDist(distance, coord, dist));
180 return points.getClosest(coord, dist);
185 double RS_Image::getDistanceToPoint(const Vector& coord,
187 RS2::ResolveLevel /*level*/,
188 double /*solidDist*/) {
193 VectorSolutions corners = getCorners();
195 double minDist = RS_MAXDOUBLE;
199 RS_Line(NULL, RS_LineData(corners.get(0), corners.get(1))),
200 RS_Line(NULL, RS_LineData(corners.get(1), corners.get(2))),
201 RS_Line(NULL, RS_LineData(corners.get(2), corners.get(3))),
202 RS_Line(NULL, RS_LineData(corners.get(3), corners.get(0)))
205 for (int i=0; i<4; ++i) {
206 dist = l[i].getDistanceToPoint(coord, NULL);
217 void RS_Image::move(Vector offset) {
218 data.insertionPoint.move(offset);
224 void RS_Image::rotate(Vector center, double angle) {
225 data.insertionPoint.rotate(center, angle);
226 data.uVector.rotate(angle);
227 data.vVector.rotate(angle);
233 void RS_Image::scale(Vector center, Vector factor) {
234 data.insertionPoint.scale(center, factor);
235 data.uVector.scale(factor);
236 data.vVector.scale(factor);
242 void RS_Image::mirror(Vector axisPoint1, Vector axisPoint2) {
243 data.insertionPoint.mirror(axisPoint1, axisPoint2);
244 data.uVector.mirror(Vector(0.0,0.0), axisPoint2-axisPoint1);
245 data.vVector.mirror(Vector(0.0,0.0), axisPoint2-axisPoint1);
249 //void RS_Image::draw(RS_Painter* painter, RS_GraphicView* view, double /*patternOffset*/) {
250 void RS_Image::draw(PaintInterface * painter, RS_GraphicView * view, double /*patternOffset*/)
252 if (painter == NULL || view == NULL || img.isNull())
256 //if (painter->getPen().getColor()==view->getBackground()) {
257 // VectorSolutions sol = getCorners();
263 int width = view->getWidth();
264 int height = view->getHeight();
266 Vector scale = Vector(view->toGuiDX(data.uVector.magnitude()),
267 view->toGuiDY(data.vVector.magnitude()));
268 double angle = data.uVector.angle();
270 int startX, stopX, startY, stopY;
272 if (data.uVector.x > 1.0e-6 && data.vVector.y > 1.0e-6)
274 startX = (int)((view->toGraphX(ox)-data.insertionPoint.x) / data.uVector.x) - 1;
281 stopX = (int)((view->toGraphX(width)-data.insertionPoint.x) / data.uVector.x) + 1;
283 if (stopX > (int)data.size.x)
285 stopX = (int)data.size.x;
288 startY = -(int)((view->toGraphY(oy) - (data.insertionPoint.y+getImageHeight())) /
296 stopY = -(int)((view->toGraphY(height) - (data.insertionPoint.y+getImageHeight())) /
299 if (stopY>(int)data.size.y)
301 stopY = (int)data.size.y;
312 painter->drawImg(img, view->toGui(data.insertionPoint), angle, scale,
313 startX, startY, stopX-startX, stopY-startY);
317 VectorSolutions sol = getCorners();
319 painter->drawLine(view->toGui(sol.get(0)), view->toGui(sol.get(1)));
320 painter->drawLine(view->toGui(sol.get(1)), view->toGui(sol.get(2)));
321 painter->drawLine(view->toGui(sol.get(2)), view->toGui(sol.get(3)));
322 painter->drawLine(view->toGui(sol.get(3)), view->toGui(sol.get(0)));
327 * Dumps the point's data to stdout.
329 std::ostream & operator<<(std::ostream & os, const RS_Image & i)
331 os << " Image: " << i.getData() << "\n";