157 lines
5.0 KiB
C++
157 lines
5.0 KiB
C++
#include "solvespace.h"
|
|
|
|
bool Constraint::HasLabel(void) {
|
|
switch(type) {
|
|
case PT_PT_DISTANCE:
|
|
return true;
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void Constraint::LineDrawOrGetDistance(Vector a, Vector b) {
|
|
if(dogd.drawing) {
|
|
glBegin(GL_LINE_STRIP);
|
|
glxVertex3v(a);
|
|
glxVertex3v(b);
|
|
glEnd();
|
|
} else {
|
|
Point2d ap = SS.GW.ProjectPoint(a);
|
|
Point2d bp = SS.GW.ProjectPoint(b);
|
|
|
|
double d = dogd.mp.DistanceToLine(ap, bp.Minus(ap), true);
|
|
dogd.dmin = min(dogd.dmin, d);
|
|
}
|
|
}
|
|
|
|
void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
|
if(!SS.GW.showConstraints) return;
|
|
|
|
// Unit vectors that describe our current view of the scene.
|
|
Vector gr = SS.GW.projRight;
|
|
Vector gu = SS.GW.projUp;
|
|
Vector gn = gr.Cross(gu);
|
|
|
|
glxColor(1, 0.3, 1);
|
|
switch(type) {
|
|
case PT_PT_DISTANCE: {
|
|
Vector ap = SS.GetEntity(ptA)->PointGetCoords();
|
|
Vector bp = SS.GetEntity(ptB)->PointGetCoords();
|
|
|
|
Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(disp.offset);
|
|
if(labelPos) *labelPos = ref;
|
|
|
|
Vector ab = ap.Minus(bp);
|
|
Vector ar = ap.Minus(ref);
|
|
// Normal to a plan containing the line and the label origin.
|
|
Vector n = ab.Cross(ar);
|
|
Vector out = ab.Cross(n).WithMagnitude(1);
|
|
out = out.ScaledBy(-out.Dot(ar));
|
|
|
|
LineDrawOrGetDistance(ap, ap.Plus(out));
|
|
LineDrawOrGetDistance(bp, bp.Plus(out));
|
|
|
|
if(dogd.drawing) {
|
|
glPushMatrix();
|
|
glxTranslatev(ref);
|
|
glxOntoCsys(gr, gu);
|
|
glxWriteText(exprA->Print());
|
|
glPopMatrix();
|
|
} else {
|
|
Point2d o = SS.GW.ProjectPoint(ref);
|
|
dogd.dmin = min(dogd.dmin, o.DistanceTo(dogd.mp) - 10);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case POINTS_COINCIDENT: {
|
|
if(!dogd.drawing) {
|
|
for(int i = 0; i < 2; i++) {
|
|
Vector p = SS.GetEntity(i == 0 ? ptA : ptB)->
|
|
PointGetCoords();
|
|
Point2d pp = SS.GW.ProjectPoint(p);
|
|
// The point is selected within a radius of 7, from the
|
|
// same center; so if the point is visible, then this
|
|
// constraint cannot be selected. But that's okay.
|
|
dogd.dmin = min(dogd.dmin, pp.DistanceTo(dogd.mp) - 3);
|
|
}
|
|
break;
|
|
}
|
|
|
|
for(int a = 0; a < 2; a++) {
|
|
Vector r = SS.GW.projRight.ScaledBy((a+1)/SS.GW.scale);
|
|
Vector d = SS.GW.projUp.ScaledBy((2-a)/SS.GW.scale);
|
|
for(int i = 0; i < 2; i++) {
|
|
Vector p = SS.GetEntity(i == 0 ? ptA : ptB)->
|
|
PointGetCoords();
|
|
glxColor(0.4, 0, 0.4);
|
|
glBegin(GL_QUADS);
|
|
glxVertex3v(p.Plus (r).Plus (d));
|
|
glxVertex3v(p.Plus (r).Minus(d));
|
|
glxVertex3v(p.Minus(r).Minus(d));
|
|
glxVertex3v(p.Minus(r).Plus (d));
|
|
glEnd();
|
|
}
|
|
|
|
}
|
|
break;
|
|
}
|
|
|
|
case PT_IN_PLANE: {
|
|
double s = 5;
|
|
Vector r = SS.GW.projRight.ScaledBy(s/SS.GW.scale);
|
|
Vector d = SS.GW.projUp.ScaledBy(s/SS.GW.scale);
|
|
Vector p = SS.GetEntity(ptA)->PointGetCoords();
|
|
LineDrawOrGetDistance(p.Plus (r).Plus (d), p.Plus (r).Minus(d));
|
|
LineDrawOrGetDistance(p.Plus (r).Minus(d), p.Minus(r).Minus(d));
|
|
LineDrawOrGetDistance(p.Minus(r).Minus(d), p.Minus(r).Plus (d));
|
|
LineDrawOrGetDistance(p.Minus(r).Plus (d), p.Plus (r).Plus (d));
|
|
break;
|
|
}
|
|
|
|
case EQUAL_LENGTH_LINES: {
|
|
for(int i = 0; i < 2; i++) {
|
|
Entity *e = SS.GetEntity(i == 0 ? entityA : entityB);
|
|
Vector a = SS.GetEntity(e->assoc[0])->PointGetCoords();
|
|
Vector b = SS.GetEntity(e->assoc[1])->PointGetCoords();
|
|
Vector m = (a.ScaledBy(1.0/3)).Plus(b.ScaledBy(2.0/3));
|
|
Vector ab = a.Minus(b);
|
|
Vector n = (gn.Cross(ab)).WithMagnitude(10/SS.GW.scale);
|
|
|
|
LineDrawOrGetDistance(m.Minus(n), m.Plus(n));
|
|
}
|
|
break;
|
|
}
|
|
|
|
default: oops();
|
|
}
|
|
}
|
|
|
|
void Constraint::Draw(void) {
|
|
dogd.drawing = true;
|
|
DrawOrGetDistance(NULL);
|
|
}
|
|
|
|
double Constraint::GetDistance(Point2d mp) {
|
|
dogd.drawing = false;
|
|
dogd.mp = mp;
|
|
dogd.dmin = 1e12;
|
|
|
|
DrawOrGetDistance(NULL);
|
|
|
|
return dogd.dmin;
|
|
}
|
|
|
|
Vector Constraint::GetLabelPos(void) {
|
|
dogd.drawing = false;
|
|
dogd.mp.x = 0; dogd.mp.y = 0;
|
|
dogd.dmin = 1e12;
|
|
|
|
Vector p;
|
|
DrawOrGetDistance(&p);
|
|
return p;
|
|
}
|
|
|