X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fline.cpp;h=9054bbc8c2bcda9be454356eb552a4e3ab76a423;hb=70297ac8ec7453e4196f4b58056bcfe4b04f2aca;hp=aa5054bab3da9ea9bb79ca65b8cf695093ccb687;hpb=3047a65eb459ddb4a85e1a694aa2b2491437472e;p=architektonas diff --git a/src/line.cpp b/src/line.cpp index aa5054b..9054bbc 100644 --- a/src/line.cpp +++ b/src/line.cpp @@ -132,8 +132,11 @@ Line::~Line() { // We can assume this, since this is a mouse down event here. objectWasDragged = false; + SaveState(); HitTest(point); +// return StateChanged(); +// this is shite. this should be checked for in the Container, not here! // If we're part of a non-top-level container, send this signal to it if (parent->type == OTContainer && !((Container *)parent)->isTopLevelContainer && (hitLine || hitPoint1 || hitPoint2)) @@ -300,8 +303,10 @@ Like so: #if 0 if (selection.normalized().contains(Extents())) #else - if (selection.normalized().contains(position.x, position.y) - && selection.normalized().contains(endpoint.x, endpoint.y)) +// if (selection.normalized().contains(position.x, position.y) +// && selection.normalized().contains(endpoint.x, endpoint.y)) + if (selection.contains(position.x, position.y) + && selection.contains(endpoint.x, endpoint.y)) #endif state = OSSelected; else @@ -310,9 +315,11 @@ Like so: return; } - // Hit test tells us what we hit (if anything) through boolean variables. It - // also tells us whether or not the state changed. - needUpdate = HitTest(point); + // Hit test tells us what we hit (if anything) through boolean variables. (It + // also tells us whether or not the state changed. --not any more) + SaveState(); + HitTest(point); + needUpdate = StateChanged(); objectWasDragged = (draggingLine | draggingHandle1 | draggingHandle2); @@ -363,16 +370,6 @@ try to do the right thing, most of the time. :-) Vector point1 = (draggingHandle1 ? endpoint : position); Vector point2 = (draggingHandle1 ? position : endpoint); -#if 0 - Vector current(point2, point1); - Vector v = current.Unit() * length; - Vector v2 = point1 + v; - - //bleh - if (!Object::fixedLength) - v2 = point2; -#endif - if (Object::fixedAngle) { // Here we calculate the component of the current vector along the fixed angle. @@ -424,22 +421,21 @@ the horizontal line or vertical line that intersects from the current mouse posi } else // endpoint { -// Vector v1 = endpoint - position; Vector v = Vector(endpoint - position).Unit() * length; endpoint = position + v; } } else { - // Otherwise, we calculate the new length, just in case on the next move - // it turns out to have a fixed length. :-) + // Otherwise, we calculate the new length, just in case on the next + // move it turns out to have a fixed length. :-) length = Vector(endpoint - position).Magnitude(); } if (!Object::fixedAngle) { - // Calculate the new angle, just in case on the next move it turns out to - // be fixed. :-) + // Calculate the new angle, just in case on the next move it turns + // out to be fixed. :-) angle = Vector(endpoint - position).Unit(); } } @@ -448,14 +444,6 @@ the horizontal line or vertical line that intersects from the current mouse posi draggingHandle1 = false; draggingHandle2 = false; -// hitPoint1 = hitPoint2 = hitLine = false; - - // Here we check for just a click: If object was clicked and dragged, then - // revert to the old state (OSInactive). Otherwise, keep the new state that - // we set. -/*Maybe it would be better to just check for "object was dragged" state and not have to worry -about keeping track of old states... -*/ if (objectWasDragged) state = oldState; } @@ -463,28 +451,23 @@ about keeping track of old states... /*virtual*/ bool Line::HitTest(Point point) { - SaveState(); +// SaveState(); hitPoint1 = hitPoint2 = hitLine = false; Vector lineSegment = endpoint - position; Vector v1 = point - position; Vector v2 = point - endpoint; - double parameterizedPoint = lineSegment.Dot(v1) / lineSegment.Magnitude(), distance; + double t = Vector::Parameter(position, endpoint, point); + double distance; // Geometric interpretation: - // The parameterized point on the vector lineSegment is where the perpendicular - // intersects lineSegment. If pp < 0, then the perpendicular lies beyond the 1st - // endpoint. If pp > length of ls, then the perpendicular lies beyond the 2nd endpoint. - - if (parameterizedPoint < 0.0) - distance = v1.Magnitude(); - else if (parameterizedPoint > lineSegment.Magnitude()) - distance = v2.Magnitude(); - else - // distance = ?Det?(ls, v1) / |ls| - distance = fabs((lineSegment.x * v1.y - v1.x * lineSegment.y) / lineSegment.Magnitude()); + // The parameter "t" on the vector lineSegment is where the normal of + // lineSegment coincides with point. If t < 0, the normal lies beyond the + // 1st endpoint. If t > 1, then the normal lies beyond the 2nd endpoint. We + // only calculate the length of the normal between the point and the + // lineSegment when the parameter is between 0 and 1. - // Geometric interpretation of the above: + // Geometric interpretation of "distance = ?Det?(ls, v1) / |ls|": // If the segment endpoints are s and e, and the point is p, then the test // for the perpendicular intercepting the segment is equivalent to insisting // that the two dot products {s-e}.{s-p} and {e-s}.{e-p} are both non-negative. @@ -502,9 +485,15 @@ about keeping track of old states... // all other rows, we end up with the matrix on the right which greatly // simplifies the calculation of the determinant. -//How do we determine distance here? Especially if zoomed in or out??? -//#warning "!!! Distances tested for may not be valid if zoomed in or out !!!" -// [FIXED] + if (t < 0.0) + distance = v1.Magnitude(); + else if (t > 1.0) + distance = v2.Magnitude(); + else + // distance = ?Det?(ls, v1) / |ls| + distance = fabs((lineSegment.x * v1.y - v1.x * lineSegment.y) + / lineSegment.Magnitude()); + if ((v1.Magnitude() * Painter::zoom) < 8.0) hitPoint1 = true; else if ((v2.Magnitude() * Painter::zoom) < 8.0) @@ -512,7 +501,8 @@ about keeping track of old states... else if ((distance * Painter::zoom) < 5.0) hitLine = true; - return StateChanged(); + return (hitPoint1 | hitPoint2 | hitLine ? true : false); +// return StateChanged(); } @@ -579,6 +569,23 @@ you then *definitely* do not want them to have the same reference number. } +/*virtual*/ void Line::Translate(Vector amount) +{ + position += amount; + endpoint += amount; +} + + +/*virtual*/ void Line::Rotate(Vector point, double angle) +{ +} + + +/*virtual*/ void Line::Scale(Vector point, double amount) +{ +} + + void Line::SetDimensionOnLine(Dimension * dimension/*=NULL*/) { // If they don't pass one in, create it for the caller.