X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fline.cpp;h=d37106e5a7846df0f9fe8fabed88aee129ea42c5;hb=9d59b5831000704a1ed39c22a6043ba658993159;hp=880a79d60bc48254645794628ce1cb69dbe246fb;hpb=baf67656b97e3d61e9223e66ebe4f554e364cd4a;p=architektonas diff --git a/src/line.cpp b/src/line.cpp index 880a79d..d37106e 100644 --- a/src/line.cpp +++ b/src/line.cpp @@ -30,8 +30,12 @@ Line::Line(Vector p1, Vector p2, Object * p/*= NULL*/): Object(p1, p), endpoint( { } + Line::~Line() { +// Taking care of connections should be done by the Container, as we don't know +// anything about any other object connected to this one. +#if 0 // If there are any attached Dimensions, we must set the attachment points // to NULL since they will no longer be valid. if (attachedDimension) @@ -42,8 +46,10 @@ Line::~Line() // IT WOULD BE NICE to have any object points attached to this line automagically // connect to this dimension object at this point, instead of just becoming // detached. +#endif } + /*virtual*/ void Line::Draw(Painter * painter) { painter->SetPen(QPen(Qt::red, 2.0, Qt::DotLine)); @@ -123,6 +129,7 @@ TODO: Make Dimension preview with modifier keys for showing on other side // (Priorities are taken care of in HitTest()...) if (hitLine) { +#if 0 if (attachedDimension == NULL) { // How to get this object into the top level container??? @@ -142,6 +149,26 @@ a dimension only) Draw() function... :-/ // If there's one already there, tell it to flip sides... attachedDimension->FlipSides(); } +#else + // New approach here: We look for connected objects. + Object * attachedDimension = FindAttachedDimension(); + + if (attachedDimension) + { + // If there's an attached Dimension, tell it to switch sides... + ((Dimension *)attachedDimension)->FlipSides(); + } + else + { + // Otherwise, we make a new one and attach it here. + attachedDimension = new Dimension(Connection(this, 0), Connection(this, 1.0), DTLinear, this); + connected.push_back(Connection(attachedDimension, 0)); + connected.push_back(Connection(attachedDimension, 1.0)); + + if (parent != NULL) + parent->Add(attachedDimension); + } +#endif return true; } @@ -213,6 +240,7 @@ Like so: return false; } + /*virtual*/ void Line::PointerMoved(Vector point) { // Hit test tells us what we hit (if anything) through boolean variables. It @@ -310,6 +338,7 @@ the horizontal line or vertical line that intersects from the current mouse posi } } + /*virtual*/ void Line::PointerReleased(void) { if (draggingHandle1 || draggingHandle2) @@ -360,6 +389,7 @@ about keeping track of old states... state = oldState; } + // Check to see if the point passed in coincides with any we have. If so, return a // pointer to it; otherwise, return NULL. /*virtual*/ Vector * Line::GetPointAt(Vector v) @@ -372,44 +402,102 @@ about keeping track of old states... return 0; } -#if 0 -void Line::SetDimensionOnPoint1(Dimension * dimension) -{ - dimPoint1 = dimension; - if (dimension) - dimension->SetPoint1(position); +/*virtual*/ void Line::Enumerate(FILE * file) +{ + fprintf(file, "LINE (%lf,%lf) (%lf,%lf)\n", position.x, position.y, endpoint.x, endpoint.y); } -void Line::SetDimensionOnPoint2(Dimension * dimension) + +/*virtual*/ Object * Line::Copy(void) { - dimPoint2 = dimension; +#warning "!!! This doesn't take care of attached Dimensions !!!" +/* +This is a real problem. While having a pointer in the Dimension to this line's points is fast & easy, +it creates a huge problem when trying to replicate an object like this. - if (dimension) - dimension->SetPoint2(endpoint); +Maybe a way to fix that then, is to have reference numbers instead of pointers. That way, if you copy +them, ... you might still have problems. Because you can't be sure if a copy will be persistant or not, +you then *definitely* do not want them to have the same reference number. +*/ + return new Line(position, endpoint, parent); } -#else + + +/*virtual*/ Vector Line::GetPointAtParameter(double parameter) +{ + if (parameter <= 0) + return position; + else if (parameter >= 1.0) + return endpoint; + + // Our parameter lies between zero and one, so calculate it! + Vector v(endpoint, position); + double length = v.Magnitude(); + // We scale the magnitude of v so that it lies between 0 and 1... + // By multiplying the parameter by the magnitude, we obtain the point we + // want. No scaling necessary as it's inherent in the approach! + double spotOnLength = length * parameter; + + // To get our point, we use the initial point of the line and add in our + // scaled point. + Vector result = position + (v * spotOnLength); + return result; +} + + void Line::SetDimensionOnLine(Dimension * dimension/*=NULL*/) { // If they don't pass one in, create it for the caller. if (dimension == NULL) { - dimension = new Dimension(&position, &endpoint, DTLinear, this); +//printf("Line::SetDimensionOnLine(): Creating new dimension...\n"); +// dimension = new Dimension(position, endpoint, DTLinear, this); + dimension = new Dimension(Connection(this, 0), Connection(this, 1.0), DTLinear, this); if (parent) +//{ +//printf("Line::SetDimensionOnLine(): Adding to parent...\n"); parent->Add(dimension); +//} + } + else + { + dimension->Connect(this, 0); + dimension->Connect(this, 1.0); } - attachedDimension = dimension; + // Make sure the Dimension is connected to us... + Connect(dimension, 0); + Connect(dimension, 1.0); +} - // After we set the points here, we don't have to care about them anymore. - if (dimension) + +Object * Line::FindAttachedDimension(void) +{ + // Is there anything connected to this line? If not, return NULL + if (connected.size() < 2) + return NULL; + + // Otherwise, we have to search our objects to see if there's a likely + // candidate. In this case, we're looking for a pointer to the same object + // with a parameter of 0 and 1 respectively. This is O((n^2)/2). + for(uint i=0; iSetPoint1(&position); - dimension->SetPoint2(&endpoint); + for(uint j=i+1; j