|
|
|
|
@@ -87,39 +87,39 @@ Subject 1.02: How do I find the distance from a point to a line?
|
|
|
|
|
|
|
|
|
|
Let the point be C (Cx,Cy) and the line be AB (Ax,Ay) to (Bx,By).
|
|
|
|
|
Let P be the point of perpendicular projection of C on AB. The parameter
|
|
|
|
|
r, which indicates P's position along AB, is computed by the dot product
|
|
|
|
|
r, which indicates P's position along AB, is computed by the dot product
|
|
|
|
|
of AC and AB divided by the square of the length of AB:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(1) AC dot AB
|
|
|
|
|
r = ---------
|
|
|
|
|
r = ---------
|
|
|
|
|
||AB||^2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r has the following meaning:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r=0 P = A
|
|
|
|
|
r=1 P = B
|
|
|
|
|
r<0 P is on the backward extension of AB
|
|
|
|
|
r>1 P is on the forward extension of AB
|
|
|
|
|
0<r<1 P is interior to AB
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The length of a line segment in d dimensions, AB is computed by:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
L = sqrt( (Bx-Ax)^2 + (By-Ay)^2 + ... + (Bd-Ad)^2)
|
|
|
|
|
|
|
|
|
|
so in 2D:
|
|
|
|
|
|
|
|
|
|
so in 2D:
|
|
|
|
|
|
|
|
|
|
L = sqrt( (Bx-Ax)^2 + (By-Ay)^2 )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
and the dot product of two vectors in d dimensions, U dot V is computed:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
D = (Ux * Vx) + (Uy * Vy) + ... + (Ud * Vd)
|
|
|
|
|
|
|
|
|
|
so in 2D:
|
|
|
|
|
|
|
|
|
|
D = (Ux * Vx) + (Uy * Vy)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
so in 2D:
|
|
|
|
|
|
|
|
|
|
D = (Ux * Vx) + (Uy * Vy)
|
|
|
|
|
|
|
|
|
|
So (1) expands to:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(Cx-Ax)(Bx-Ax) + (Cy-Ay)(By-Ay)
|
|
|
|
|
r = -------------------------------
|
|
|
|
|
L^2
|
|
|
|
|
@@ -131,7 +131,7 @@ Subject 1.02: How do I find the distance from a point to a line?
|
|
|
|
|
|
|
|
|
|
And the distance from A to P = r*L.
|
|
|
|
|
|
|
|
|
|
Use another parameter s to indicate the location along PC, with the
|
|
|
|
|
Use another parameter s to indicate the location along PC, with the
|
|
|
|
|
following meaning:
|
|
|
|
|
s<0 C is left of AB
|
|
|
|
|
s>0 C is right of AB
|
|
|
|
|
@@ -155,7 +155,7 @@ Subject 1.02: How do I find the distance from a point to a line?
|
|
|
|
|
//
|
|
|
|
|
double px = ax + r*(bx-ax);
|
|
|
|
|
double py = ay + r*(by-ay);
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
double s = ((ay-cy)*(bx-ax)-(ax-cx)*(by-ay) ) / r_denomenator;
|
|
|
|
|
|
|
|
|
|
distanceLine = fabs(s)*sqrt(r_denomenator);
|
|
|
|
|
@@ -196,10 +196,10 @@ Subject 1.02: How do I find the distance from a point to a line?
|
|
|
|
|
|
|
|
|
|
// Vind de hoek van de edge van ps die het dichts bij pt ligt
|
|
|
|
|
// (het maakt ons niet uit of pt er binnen of buiten ligt)
|
|
|
|
|
// A = P2Y - P1Y
|
|
|
|
|
// B = P1X - P2X
|
|
|
|
|
// C = P2X * P1Y - P2Y * P1X
|
|
|
|
|
// DistToLine = Abs((A * PX + B * PY + C) / Sqr(A * A + B * B))
|
|
|
|
|
// A = P2Y - P1Y
|
|
|
|
|
// B = P1X - P2X
|
|
|
|
|
// C = P2X * P1Y - P2Y * P1X
|
|
|
|
|
// DistToLine = Abs((A * PX + B * PY + C) / Sqr(A * A + B * B))
|
|
|
|
|
/*static*/ void CSLNKContourImpl::EdgeAngle(const WT_Logical_Point pt, const WT_Point_Set &ps, double &EdgeAngle, double &EdgeDistance)
|
|
|
|
|
{
|
|
|
|
|
double ptx = pt.m_x;
|
|
|
|
|
@@ -217,11 +217,11 @@ Subject 1.02: How do I find the distance from a point to a line?
|
|
|
|
|
pt1.m_x, pt1.m_y,
|
|
|
|
|
pt2.m_x, pt2.m_y,
|
|
|
|
|
DistSeg, DistLine);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Bij een 'ingedeukte' ruimte kan DistSeg == minDistSeg zijn. Dan wil
|
|
|
|
|
// je juist een zo'n groot mogelijke afstand tot de virtuele projectie
|
|
|
|
|
if (DistSeg < minDistSeg || (DistSeg == minDistSeg && DistLine > minDistLine))
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
long dy = pt2.m_y - pt1.m_y;
|
|
|
|
|
long dx = pt2.m_x - pt1.m_x;
|
|
|
|
|
|
|
|
|
|
@@ -243,7 +243,7 @@ Subject 1.02: How do I find the distance from a point to a line?
|
|
|
|
|
EdgeDistance = minDistLine; //We rekenen met Seg maar projecteren uiteindelijk op Line
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Signed Area needed for centroid!
|
|
|
|
|
// Signed Area needed for centroid!
|
|
|
|
|
// Negative is clockwise, Positve counterclockwise
|
|
|
|
|
/*static*/double CSLNKContourImpl::DWFArea(const WT_Point_Set &pg)
|
|
|
|
|
{
|
|
|
|
|
@@ -322,7 +322,9 @@ WT_Logical_Point CSLNKContourImpl::LabelPosition(LABELPOS pos /*= LABEL_DEFAULT*
|
|
|
|
|
return WT_Logical_Point((WT_Integer32)(ptx / dDWFArea6), (WT_Integer32)(pty / dDWFArea6));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CSLNKContourImpl::SerializeLabel(WT_File &my_file, LABELPOS pos, int fontheight, HDC myDC)
|
|
|
|
|
void CSLNKContourImpl::SerializeLabel(WT_File &my_file, LABELPOS pos,
|
|
|
|
|
int fontheight, double scale,
|
|
|
|
|
HDC myDC)
|
|
|
|
|
{
|
|
|
|
|
if (m_Color.rgba().m_rgb.a==255)
|
|
|
|
|
{ // Volle achtergrond kleur
|
|
|
|
|
@@ -345,7 +347,7 @@ void CSLNKContourImpl::SerializeLabel(WT_File &my_file, LABELPOS pos, int fonthe
|
|
|
|
|
tok.Replace("[BR]", "\n"); // We ondersteunen ook [BR] als newline
|
|
|
|
|
|
|
|
|
|
WT_Logical_Point ptTxt = LabelPosition(pos);
|
|
|
|
|
// De wiskundige label-positie is bepaald. Nu iets corrigeren om
|
|
|
|
|
// De wiskundige label-positie is bepaald. Nu iets corrigeren om
|
|
|
|
|
// (afhankelijk van het font) mooier te zijn
|
|
|
|
|
// Ook eventueel hori/vert centreren
|
|
|
|
|
int width = -1; // Voor UBB code [c] van centreren
|
|
|
|
|
@@ -361,7 +363,7 @@ void CSLNKContourImpl::SerializeLabel(WT_File &my_file, LABELPOS pos, int fonthe
|
|
|
|
|
{
|
|
|
|
|
// Eerst een keer simuleren om grootte te bepalen
|
|
|
|
|
ATLASSERT(myDC!=NULL);
|
|
|
|
|
WT_Logical_Point ptBR = DrawOneLabel(my_file, pos, ptTxt, tok, fontheight, myDC);
|
|
|
|
|
WT_Logical_Point ptBR = DrawOneLabel(my_file, ptTxt, tok, fontheight, scale, myDC);
|
|
|
|
|
width = (ptBR.m_x - ptTxt.m_x);
|
|
|
|
|
ptTxt.m_y -= (ptBR.m_y - ptTxt.m_y)/2 + fontheight*9/10;
|
|
|
|
|
ptTxt.m_x += fontheight/4;
|
|
|
|
|
@@ -371,7 +373,7 @@ void CSLNKContourImpl::SerializeLabel(WT_File &my_file, LABELPOS pos, int fonthe
|
|
|
|
|
{
|
|
|
|
|
// Eerst een keer simuleren om grootte te bepalen
|
|
|
|
|
ATLASSERT(myDC!=NULL);
|
|
|
|
|
WT_Logical_Point ptBR = DrawOneLabel(my_file, pos, ptTxt, tok, fontheight, myDC);
|
|
|
|
|
WT_Logical_Point ptBR = DrawOneLabel(my_file, ptTxt, tok, fontheight, scale, myDC);
|
|
|
|
|
width = (ptBR.m_x - ptTxt.m_x);
|
|
|
|
|
ptTxt.m_y -= fontheight;
|
|
|
|
|
ptTxt.m_x -= (ptBR.m_x - ptTxt.m_x)/2;
|
|
|
|
|
@@ -383,7 +385,7 @@ void CSLNKContourImpl::SerializeLabel(WT_File &my_file, LABELPOS pos, int fonthe
|
|
|
|
|
if (!CSLNKContourImpl::PointInPolygon(ptTxt, *this))
|
|
|
|
|
ptTxt = LabelPosition(CSLNKContourImpl::LABEL_DEFAULT);
|
|
|
|
|
// Eerst een keer simuleren om grootte te bepalen
|
|
|
|
|
WT_Logical_Point ptBR = DrawOneLabel(my_file, pos, ptTxt, tok, fontheight, myDC);
|
|
|
|
|
WT_Logical_Point ptBR = DrawOneLabel(my_file, ptTxt, tok, fontheight, scale, myDC);
|
|
|
|
|
width = (ptBR.m_x - ptTxt.m_x);
|
|
|
|
|
ptTxt.m_x -= (ptBR.m_x - ptTxt.m_x)/2;
|
|
|
|
|
ptTxt.m_y -= (ptBR.m_y - ptTxt.m_y)/2 + fontheight*9/10;
|
|
|
|
|
@@ -400,7 +402,7 @@ pm.serialize(my_file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Nu echt tekenen met width<>-2
|
|
|
|
|
DrawOneLabel(my_file, pos, ptTxt, tok, fontheight, myDC, width);
|
|
|
|
|
DrawOneLabel(my_file, ptTxt, tok, fontheight, scale, myDC, width);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Draw one (possibly multline) label
|
|
|
|
|
@@ -409,15 +411,15 @@ pm.serialize(my_file);
|
|
|
|
|
// Als width==-1 is centreren niet mogelijk/nodig
|
|
|
|
|
// Als width>0 is centreren mogelijk via [c]
|
|
|
|
|
WT_Logical_Point CSLNKContourImpl::DrawOneLabel(WT_File &my_file,
|
|
|
|
|
LABELPOS pos,
|
|
|
|
|
WT_Logical_Point ptTxt,
|
|
|
|
|
CString tok,
|
|
|
|
|
int fontheight,
|
|
|
|
|
int fontheight,
|
|
|
|
|
double scale,
|
|
|
|
|
HDC myDC,
|
|
|
|
|
int width/*=-2*/)// Voor centreren. Moet aanroeper al een keer bepaald hebben
|
|
|
|
|
{
|
|
|
|
|
long max_width=0; // Bepaal hiermee 'rechtsonder' van de tekst als myDC
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//TODO: UBB sluitcodes ondersteunen
|
|
|
|
|
int curpos = 0;
|
|
|
|
|
CString token = tok.Tokenize("\n", curpos);
|
|
|
|
|
@@ -425,9 +427,12 @@ WT_Logical_Point CSLNKContourImpl::DrawOneLabel(WT_File &my_file,
|
|
|
|
|
bool centering=false;
|
|
|
|
|
while( token != "" )
|
|
|
|
|
{
|
|
|
|
|
// invariant (ook bij binnenkomst): ptTxt.m_y bevat het linksonderpunt van de huidige regel
|
|
|
|
|
// uitgaande van fontheight. Bij [s] gebruik moeten we dus corrigeren
|
|
|
|
|
//CString f(token);
|
|
|
|
|
int skipextra = 0; // Extra skip bij underline
|
|
|
|
|
long size=100;
|
|
|
|
|
int thisLineHeight=fontheight; // mooie default
|
|
|
|
|
|
|
|
|
|
// Supported UBB-like codes:
|
|
|
|
|
// [[This is literal text in square brackets]
|
|
|
|
|
@@ -435,9 +440,10 @@ WT_Logical_Point CSLNKContourImpl::DrawOneLabel(WT_File &my_file,
|
|
|
|
|
// [b]This text is bold
|
|
|
|
|
// [u]This text is underline
|
|
|
|
|
// [cFF00FF]This text is colored
|
|
|
|
|
// [s50]This text is 50% sized
|
|
|
|
|
// [s50]This text is 50% sized van standaard labelfont
|
|
|
|
|
// [S800]This text is 800 height sized
|
|
|
|
|
// Bovenstaand alleen voor de huidige regel
|
|
|
|
|
// [c] Centreer alle regels binnen bounding box (anders links gealigned)
|
|
|
|
|
// [c] Centreer alle(!) volgende regels binnen bounding box (anders links gealigned)
|
|
|
|
|
while (token[0] == '[')
|
|
|
|
|
{
|
|
|
|
|
token.Delete(0);
|
|
|
|
|
@@ -467,7 +473,7 @@ WT_Logical_Point CSLNKContourImpl::DrawOneLabel(WT_File &my_file,
|
|
|
|
|
if (end==1)
|
|
|
|
|
{
|
|
|
|
|
token.Delete(0);
|
|
|
|
|
if (width>0) centering = true;
|
|
|
|
|
centering = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (end >= 0)
|
|
|
|
|
@@ -485,15 +491,21 @@ WT_Logical_Point CSLNKContourImpl::DrawOneLabel(WT_File &my_file,
|
|
|
|
|
}
|
|
|
|
|
case 's': // Size
|
|
|
|
|
{
|
|
|
|
|
BOOL bigS = (token[0]=='S');
|
|
|
|
|
int end = token.Find(']');
|
|
|
|
|
if (end >= 0)
|
|
|
|
|
{
|
|
|
|
|
if (sscanf(token, "s%d]", &size))
|
|
|
|
|
token.Delete(0);
|
|
|
|
|
if (sscanf(token, "%d]", &size))
|
|
|
|
|
{
|
|
|
|
|
int fh = myRound(double(size)*fontheight/100);
|
|
|
|
|
ptTxt.m_y += (fontheight - fh);
|
|
|
|
|
if (bigS)
|
|
|
|
|
thisLineHeight = myRound(size * scale);
|
|
|
|
|
else
|
|
|
|
|
thisLineHeight = myRound(double(size)*fontheight/100);
|
|
|
|
|
|
|
|
|
|
ptTxt.m_y -= (thisLineHeight - fontheight); // Correctie op de invariant voor huidige regel
|
|
|
|
|
if (width != -2)
|
|
|
|
|
my_file.desired_rendition().font().height() = fh;
|
|
|
|
|
my_file.desired_rendition().font().height() = thisLineHeight;
|
|
|
|
|
}
|
|
|
|
|
token.Delete(0, end);
|
|
|
|
|
}
|
|
|
|
|
@@ -511,7 +523,7 @@ WT_Logical_Point CSLNKContourImpl::DrawOneLabel(WT_File &my_file,
|
|
|
|
|
RECT rc = { 0, 0, 0, 0};
|
|
|
|
|
DrawText(myDC, token, token.GetLength(), &rc, DT_CALCRECT); // Grootte bepalen
|
|
|
|
|
// Tekst horizontaal centreren
|
|
|
|
|
horoffset = width/2 - MulDiv(rc.right*size/100,fontheight,FONT_SIZER)/2;
|
|
|
|
|
horoffset = width/2 - MulDiv(rc.right,thisLineHeight,FONT_SIZER)/2;
|
|
|
|
|
}
|
|
|
|
|
WT_String txt;
|
|
|
|
|
if (WT_String::is_ascii(token.GetLength(), token))
|
|
|
|
|
@@ -543,7 +555,7 @@ WT_Logical_Point CSLNKContourImpl::DrawOneLabel(WT_File &my_file,
|
|
|
|
|
|
|
|
|
|
// Tekst horizontaal en verticaal centreren
|
|
|
|
|
// ptRes.m_y += rc.bottom; halen we wel uit ptY
|
|
|
|
|
max_width = max(max_width, MulDiv(rc.right,size,100));
|
|
|
|
|
max_width = max(max_width, MulDiv(rc.right,thisLineHeight,fontheight));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
line ++;
|
|
|
|
|
@@ -568,7 +580,7 @@ WT_Logical_Point CSLNKContourImpl::DrawOneLabel(WT_File &my_file,
|
|
|
|
|
- (m_fromSymbol) Symbool (al dan niet met m_Key gedefinieerd)
|
|
|
|
|
- Ingebouwd (star)
|
|
|
|
|
- Gedefinieerd (bounding octagon)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Als solidOnly dan alleen als alpha==255 en een label (wel herkend)
|
|
|
|
|
****************************************************************************/
|
|
|
|
|
WT_Result CSLNKContourImpl::serialize(WT_File & file, BOOL solidOnly)
|
|
|
|
|
@@ -588,7 +600,7 @@ WT_Result CSLNKContourImpl::serialize(WT_File & file, BOOL solidOnly)
|
|
|
|
|
{ // We have got a proper label/contour
|
|
|
|
|
if (m_fromSymbol ||
|
|
|
|
|
(m_Color.rgba().m_rgb.a==255 && solidOnly) ||
|
|
|
|
|
(m_Color.rgba().m_rgb.a<255 && !solidOnly))
|
|
|
|
|
(m_Color.rgba().m_rgb.a<255 && !solidOnly))
|
|
|
|
|
{
|
|
|
|
|
// Start a node for 'everything'. Dit is wat we concreet teruggeven bij klikken in de tekening
|
|
|
|
|
WT_Object_Node my_node(file,m_next_node_num++,m_Key);
|
|
|
|
|
@@ -617,11 +629,11 @@ WT_Result CSLNKContourImpl::serialize(WT_File & file, BOOL solidOnly)
|
|
|
|
|
WT_RGBA32 rgba[3];
|
|
|
|
|
WT_RGBA32 clr(this.m_Color.rgba());
|
|
|
|
|
rgba[0] = clr;
|
|
|
|
|
rgba[1] = WT_RGBA32 (clr.m_rgb.r+64>255?255:clr.m_rgb.r+64,
|
|
|
|
|
clr.m_rgb.g+64>255?255:clr.m_rgb.g+64,
|
|
|
|
|
rgba[1] = WT_RGBA32 (clr.m_rgb.r+64>255?255:clr.m_rgb.r+64,
|
|
|
|
|
clr.m_rgb.g+64>255?255:clr.m_rgb.g+64,
|
|
|
|
|
clr.m_rgb.b+64>255?255:clr.m_rgb.b+64, clr.m_rgb.a);
|
|
|
|
|
rgba[1] = WT_RGBA32 (clr.m_rgb.r-64<0?0:clr.m_rgb.r-64,
|
|
|
|
|
clr.m_rgb.g-64<0?0:clr.m_rgb.g-64,
|
|
|
|
|
rgba[1] = WT_RGBA32 (clr.m_rgb.r-64<0?0:clr.m_rgb.r-64,
|
|
|
|
|
clr.m_rgb.g-64<0?0:clr.m_rgb.g-64,
|
|
|
|
|
clr.m_rgb.b-64<0?0:clr.m_rgb.b-64, clr.m_rgb.a);
|
|
|
|
|
rgba[2] = rgba[1];
|
|
|
|
|
|
|
|
|
|
|