v2.10 Symbool rotatie
svn path=/Slnkdwf/trunk/; revision=12485
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
#include "slnkcontourImpl.h"
|
||||
#include <math.h>
|
||||
|
||||
#ifndef PI
|
||||
#define PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define PALETTE_RED 1 // Color in the default colormap is red.
|
||||
|
||||
/*static*/ WT_Integer32 CSLNKContourImpl::m_next_node_num = 0; // Eigenlijk initialiseren op laatste van planfile
|
||||
@@ -61,9 +65,187 @@ BOOL CSLNKContourImpl::PointInPolygon(const CPoint pt, const CPoint *ps, int siz
|
||||
return c;
|
||||
}
|
||||
|
||||
// http://www.codeguru.com/forum/printthread.php?t=194400
|
||||
void DistanceFromLine(double cx, double cy, double ax, double ay ,
|
||||
double bx, double by, double &distanceSegment,
|
||||
double &distanceLine)
|
||||
{
|
||||
|
||||
//
|
||||
// find the distance from the point (cx,cy) to the line
|
||||
// determined by the points (ax,ay) and (bx,by)
|
||||
//
|
||||
// distanceSegment = distance from the point to the line segment
|
||||
// distanceLine = distance from the point to the line (assuming
|
||||
// infinite extent in both directions
|
||||
//
|
||||
|
||||
/*
|
||||
|
||||
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
|
||||
of AC and AB divided by the square of the length of AB:
|
||||
|
||||
(1) AC dot AB
|
||||
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:
|
||||
|
||||
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 (1) expands to:
|
||||
|
||||
(Cx-Ax)(Bx-Ax) + (Cy-Ay)(By-Ay)
|
||||
r = -------------------------------
|
||||
L^2
|
||||
|
||||
The point P can then be found:
|
||||
|
||||
Px = Ax + r(Bx-Ax)
|
||||
Py = Ay + r(By-Ay)
|
||||
|
||||
And the distance from A to P = r*L.
|
||||
|
||||
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
|
||||
s=0 C is on AB
|
||||
|
||||
Compute s as follows:
|
||||
|
||||
(Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
|
||||
s = -----------------------------
|
||||
L^2
|
||||
|
||||
|
||||
Then the distance from C to P = |s|*L.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
double r_numerator = (cx-ax)*(bx-ax) + (cy-ay)*(by-ay);
|
||||
double r_denomenator = (bx-ax)*(bx-ax) + (by-ay)*(by-ay);
|
||||
double r = r_numerator / r_denomenator;
|
||||
//
|
||||
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);
|
||||
|
||||
//
|
||||
// (xx,yy) is the point on the lineSegment closest to (cx,cy)
|
||||
//
|
||||
double xx = px;
|
||||
double yy = py;
|
||||
|
||||
if ( (r >= 0) && (r <= 1) )
|
||||
{
|
||||
distanceSegment = distanceLine;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
double dist1 = (cx-ax)*(cx-ax) + (cy-ay)*(cy-ay);
|
||||
double dist2 = (cx-bx)*(cx-bx) + (cy-by)*(cy-by);
|
||||
if (dist1 < dist2)
|
||||
{
|
||||
xx = ax;
|
||||
yy = ay;
|
||||
distanceSegment = sqrt(dist1);
|
||||
}
|
||||
else
|
||||
{
|
||||
xx = bx ;
|
||||
yy = by;
|
||||
distanceSegment = sqrt(dist2);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 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))
|
||||
/*static*/ void CSLNKContourImpl::EdgeAngle(const WT_Logical_Point pt, const WT_Point_Set &ps, double &EdgeAngle, double &EdgeDistance)
|
||||
{
|
||||
double ptx = pt.m_x;
|
||||
double pty = pt.m_y;
|
||||
int i, j, c = 0;
|
||||
double minDistSeg = 0x7FFFFFFF; // Max WT_Integer32
|
||||
double minDistLine;
|
||||
double angle = 0.0;
|
||||
myTRACE("\npt = %d,%d", pt.m_x, pt.m_y);
|
||||
for (i = 0, j = ps.count()-1; i < ps.count(); j = i++) {
|
||||
WT_Logical_Point pt1 = ps.points()[i];
|
||||
WT_Logical_Point pt2 = ps.points()[j];
|
||||
double DistSeg, DistLine;
|
||||
DistanceFromLine(pt.m_x, pt.m_y,
|
||||
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;
|
||||
|
||||
//ASSERT(!(dx == 0 && dy == 0));
|
||||
|
||||
angle = atan2((double)dy, (double)dx) * (180 / PI); // Tussen -180 en +180
|
||||
if (dy==0) if (dx<0) angle=-180; else angle=0;
|
||||
|
||||
myTRACE("\nDist %.1f angle set to: %.3f", DistSeg, angle);
|
||||
minDistSeg = DistSeg;
|
||||
minDistLine = DistLine;
|
||||
}
|
||||
}
|
||||
if (DWFArea(ps) < 0)
|
||||
EdgeAngle = angle;
|
||||
else
|
||||
EdgeAngle = 180+angle;
|
||||
if (EdgeAngle < 0) EdgeAngle += 360;
|
||||
EdgeDistance = minDistLine; //We rekenen met Seg maar projecteren uiteindelijk op Line
|
||||
}
|
||||
|
||||
// Signed Area needed for centroid!
|
||||
// Negative is clockwise, Positve counterclockwise
|
||||
/*static*/double CSLNKContourImpl::DWFArea(const WT_Polygon &pg)
|
||||
/*static*/double CSLNKContourImpl::DWFArea(const WT_Point_Set &pg)
|
||||
{
|
||||
int i;
|
||||
double area = 0;
|
||||
@@ -121,7 +303,7 @@ WT_Logical_Point CSLNKContourImpl::LabelPosition(LABELPOS pos /*= LABEL_DEFAULT*
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/WT_Logical_Point CSLNKContourImpl::Centroid(const WT_Polygon &pg)
|
||||
/*static*/WT_Logical_Point CSLNKContourImpl::Centroid(const WT_Point_Set &pg)
|
||||
{
|
||||
double ptx = 0;
|
||||
double pty = 0;
|
||||
@@ -393,11 +575,14 @@ WT_Result CSLNKContourImpl::serialize(WT_File & file, BOOL solidOnly)
|
||||
{
|
||||
if (!m_fromSymbol && m_contLabel == "" && !solidOnly) // Alleen bij tweede slag
|
||||
{ // May very well be a textobject itself, just emit it
|
||||
#ifdef _DEBUG
|
||||
// niet meer in release-mode
|
||||
file.desired_rendition().color() =
|
||||
WT_Color(PALETTE_RED, file.desired_rendition().color_map());
|
||||
file.desired_rendition().line_weight() = 0;
|
||||
WT_Polyline my_line( count(), points(), WD_False);
|
||||
my_line.serialize(file);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{ // We have got a proper label/contour
|
||||
|
||||
Reference in New Issue
Block a user