Skip to content

Commit

Permalink
fixes #3018
Browse files Browse the repository at this point in the history
  • Loading branch information
abdullahtahiriyo authored and wwmayer committed May 26, 2017
1 parent b604b27 commit c6e0c6a
Showing 1 changed file with 130 additions and 101 deletions.
231 changes: 130 additions & 101 deletions src/Mod/Sketcher/Gui/CommandCreateGeo.cpp
Expand Up @@ -93,14 +93,31 @@ the location of the centerpoint.
*/
Base::Vector2d GetCircleCenter (const Base::Vector2d &p1, const Base::Vector2d &p2, const Base::Vector2d &p3)
{
double m12p = (p1.x - p2.x) / (p2.y - p1.y);
double m23p = (p2.x - p3.x) / (p3.y - p2.y);
double x = 1/( 2*(m12p - m23p) ) * ( m12p*(p1.x + p2.x) -
m23p*(p2.x + p3.x) +
p3.y - p1.y );
double y = m12p * ( x - (p1.x + p2.x)/2 ) + (p1.y + p2.y)/2;

return Base::Vector2d(x, y);
Base::Vector2d u = p2-p1;
Base::Vector2d v = p3-p2;
Base::Vector2d w = p1-p3;

double uu = u*u;
double vv = v*v;
double ww = w*w;

double uv = -(u*v);
double vw = -(v*w);
double uw = -(u*w);

double w0 = (2 * sqrt(uu * ww - uw * uw) * uw / (uu * ww));
double w1 = (2 * sqrt(uu * vv - uv * uv) * uv / (uu * vv));
double w2 = (2 * sqrt(vv * ww - vw * vw) * vw / (vv * ww));

double wx = w0 + w1 + w2;

if( wx == 0)
THROWM(Base::ValueError,"Points are collinear");

double x = (w0*p1.x + w1*p2.x + w2*p3.x)/wx;
double y = (w0*p1.y + w1*p2.y + w2*p3.y)/wx;

return Base::Vector2d(x, y);
}

void ActivateHandler(Gui::Document *doc,DrawSketchHandler *handler)
Expand Down Expand Up @@ -1655,67 +1672,73 @@ class DrawSketchHandler3PointArc : public DrawSketchHandler
centerline with a point. It happens because the direction the curve is being drawn
reverses.
*/
CenterPoint = EditCurve[30] = GetCircleCenter(FirstPoint, SecondPoint, onSketchPos);
radius = (SecondPoint - CenterPoint).Length();

double angle1 = GetPointAngle(CenterPoint, FirstPoint);
double angle2 = GetPointAngle(CenterPoint, SecondPoint);
double angle3 = GetPointAngle(CenterPoint, onSketchPos);

// Always build arc counter-clockwise
// Point 3 is between Point 1 and 2
if ( angle3 > min(angle1, angle2) && angle3 < max(angle1, angle2) ) {
if (angle2 > angle1) {
EditCurve[0] = FirstPoint;
EditCurve[29] = SecondPoint;
arcPos1 = Sketcher::start;
arcPos2 = Sketcher::end;
}
else {
EditCurve[0] = SecondPoint;
EditCurve[29] = FirstPoint;
arcPos1 = Sketcher::end;
arcPos2 = Sketcher::start;
}
startAngle = min(angle1, angle2);
endAngle = max(angle1, angle2);
arcAngle = endAngle - startAngle;
}
// Point 3 is not between Point 1 and 2
else {
if (angle2 > angle1) {
EditCurve[0] = SecondPoint;
EditCurve[29] = FirstPoint;
arcPos1 = Sketcher::end;
arcPos2 = Sketcher::start;
try {
CenterPoint = EditCurve[30] = GetCircleCenter(FirstPoint, SecondPoint, onSketchPos);

radius = (SecondPoint - CenterPoint).Length();

double angle1 = GetPointAngle(CenterPoint, FirstPoint);
double angle2 = GetPointAngle(CenterPoint, SecondPoint);
double angle3 = GetPointAngle(CenterPoint, onSketchPos);

// Always build arc counter-clockwise
// Point 3 is between Point 1 and 2
if ( angle3 > min(angle1, angle2) && angle3 < max(angle1, angle2) ) {
if (angle2 > angle1) {
EditCurve[0] = FirstPoint;
EditCurve[29] = SecondPoint;
arcPos1 = Sketcher::start;
arcPos2 = Sketcher::end;
}
else {
EditCurve[0] = SecondPoint;
EditCurve[29] = FirstPoint;
arcPos1 = Sketcher::end;
arcPos2 = Sketcher::start;
}
startAngle = min(angle1, angle2);
endAngle = max(angle1, angle2);
arcAngle = endAngle - startAngle;
}
// Point 3 is not between Point 1 and 2
else {
EditCurve[0] = FirstPoint;
EditCurve[29] = SecondPoint;
arcPos1 = Sketcher::start;
arcPos2 = Sketcher::end;
if (angle2 > angle1) {
EditCurve[0] = SecondPoint;
EditCurve[29] = FirstPoint;
arcPos1 = Sketcher::end;
arcPos2 = Sketcher::start;
}
else {
EditCurve[0] = FirstPoint;
EditCurve[29] = SecondPoint;
arcPos1 = Sketcher::start;
arcPos2 = Sketcher::end;
}
startAngle = max(angle1, angle2);
endAngle = min(angle1, angle2);
arcAngle = 2*M_PI - (startAngle - endAngle);
}
startAngle = max(angle1, angle2);
endAngle = min(angle1, angle2);
arcAngle = 2*M_PI - (startAngle - endAngle);
}

// Build a 30 point circle ignoring already constructed points
for (int i=1; i <= 28; i++) {
double angle = startAngle + i*arcAngle/29.0; // N point arc has N-1 segments
EditCurve[i] = Base::Vector2d(CenterPoint.x + radius*cos(angle),
CenterPoint.y + radius*sin(angle));
}
// Build a 30 point circle ignoring already constructed points
for (int i=1; i <= 28; i++) {
double angle = startAngle + i*arcAngle/29.0; // N point arc has N-1 segments
EditCurve[i] = Base::Vector2d(CenterPoint.x + radius*cos(angle),
CenterPoint.y + radius*sin(angle));
}

SbString text;
text.sprintf(" (%.1fR,%.1fdeg)", (float) radius, (float) arcAngle * 180 / M_PI);
setPositionText(onSketchPos, text);
SbString text;
text.sprintf(" (%.1fR,%.1fdeg)", (float) radius, (float) arcAngle * 180 / M_PI);
setPositionText(onSketchPos, text);

sketchgui->drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.0,0.0),
AutoConstraint::CURVE)) {
renderSuggestConstraintsCursor(sugConstr3);
return;
sketchgui->drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.0,0.0),
AutoConstraint::CURVE)) {
renderSuggestConstraintsCursor(sugConstr3);
return;
}
}
catch(Base::ValueError &e) {
e.ReportException();
}
}
applyCursor();
Expand Down Expand Up @@ -5000,48 +5023,54 @@ class DrawSketchHandler3PointCircle : public DrawSketchHandler
}
}
else if (Mode == STATUS_SEEK_Second || Mode == STATUS_SEEK_Third) {
if (Mode == STATUS_SEEK_Second)
CenterPoint = EditCurve[N+1] = (onSketchPos - FirstPoint)/2 + FirstPoint;
else
CenterPoint = EditCurve[N+1] = GetCircleCenter(FirstPoint, SecondPoint, onSketchPos);
radius = (onSketchPos - CenterPoint).Length();
double lineAngle = GetPointAngle(CenterPoint, onSketchPos);

// Build a N point circle
for (int i=1; i < N; i++) {
// Start at current angle
double angle = i*2*M_PI/N + lineAngle; // N point closed circle has N segments
EditCurve[i] = Base::Vector2d(CenterPoint.x + radius*cos(angle),
CenterPoint.y + radius*sin(angle));
}
// Beginning and end of curve should be exact
EditCurve[0] = EditCurve[N] = onSketchPos;

// Display radius and start angle
// This lineAngle will report counter-clockwise from +X, not relatively
SbString text;
text.sprintf(" (%.1fR,%.1fdeg)", (float) radius, (float) lineAngle * 180 / M_PI);
setPositionText(onSketchPos, text);
try
{
if (Mode == STATUS_SEEK_Second)
CenterPoint = EditCurve[N+1] = (onSketchPos - FirstPoint)/2 + FirstPoint;
else
CenterPoint = EditCurve[N+1] = GetCircleCenter(FirstPoint, SecondPoint, onSketchPos);
radius = (onSketchPos - CenterPoint).Length();
double lineAngle = GetPointAngle(CenterPoint, onSketchPos);

// Build a N point circle
for (int i=1; i < N; i++) {
// Start at current angle
double angle = i*2*M_PI/N + lineAngle; // N point closed circle has N segments
EditCurve[i] = Base::Vector2d(CenterPoint.x + radius*cos(angle),
CenterPoint.y + radius*sin(angle));
}
// Beginning and end of curve should be exact
EditCurve[0] = EditCurve[N] = onSketchPos;

// Display radius and start angle
// This lineAngle will report counter-clockwise from +X, not relatively
SbString text;
text.sprintf(" (%.1fR,%.1fdeg)", (float) radius, (float) lineAngle * 180 / M_PI);
setPositionText(onSketchPos, text);

sketchgui->drawEdit(EditCurve);
if (Mode == STATUS_SEEK_Second) {
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f,0.f),
AutoConstraint::CURVE)) {
// Disable tangent snap on 2nd point
if (sugConstr2.back().Type == Sketcher::Tangent)
sugConstr2.pop_back();
else
renderSuggestConstraintsCursor(sugConstr2);
return;
sketchgui->drawEdit(EditCurve);
if (Mode == STATUS_SEEK_Second) {
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f,0.f),
AutoConstraint::CURVE)) {
// Disable tangent snap on 2nd point
if (sugConstr2.back().Type == Sketcher::Tangent)
sugConstr2.pop_back();
else
renderSuggestConstraintsCursor(sugConstr2);
return;
}
}
}
else {
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.0,0.0),
AutoConstraint::CURVE)) {
renderSuggestConstraintsCursor(sugConstr3);
return;
else {
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.0,0.0),
AutoConstraint::CURVE)) {
renderSuggestConstraintsCursor(sugConstr3);
return;
}
}
}
catch(Base::ValueError &e) {
e.ReportException();
}
}
applyCursor();
}
Expand Down

0 comments on commit c6e0c6a

Please sign in to comment.