#include "pline.h"
#include <ads/ListIter.h>
#include <math.h>
pline::pline( struct resbuf *_rb ) : ADS_ENT_OBJ( _rb )
{
assert(rb != NULL);
struct resbuf *temp_rb = rb;
while( temp_rb != NULL )
{
if (temp_rb->restype < 0) // possible -1 of -2
{
name[0] = temp_rb->resval.rlname[0];
name[1] = temp_rb->resval.rlname[1];
}
else if (temp_rb->restype == 5)
{
_handle = temp_rb->resval.rstring;
}
temp_rb = temp_rb->rbnext;
}
}
void pline::get_points()
{
ads_name ent, result;
ent[0] = name[0];
ent[1] = name[1];
char seqend = 0;
while(ads_entnext(ent, result) == RTNORM && seqend == 0)
{
struct resbuf *temp_rb, *point_rb;
point_rb = temp_rb = ads_entget(result);
assert(temp_rb != NULL);
while (point_rb != NULL)
{
if (point_rb->restype == 10 )
{
vec3 point(point_rb->resval.rpoint[X],
point_rb->resval.rpoint[Y],
point_rb->resval.rpoint[Z]);
vertices.append(point);
break;
}
else if (point_rb->restype == -2)
{
seqend++;
break;
}
point_rb = point_rb->rbnext;
}
ads_relrb(temp_rb);
ent[0] = result[0];
ent[1] = result[1];
}
}
double pline::nearest(const vec3 &p)
{
if (vertices.isEmpty())
get_points();
ListIterators<vec3> iterator(vertices);
iterator.reset();
vec3 n, r0, r1 = *(iterator.currentItem());
double t, temp_d, d = (p - r1).length2();
for (iterator.next(); !iterator.isDone(); iterator.next() )
{
r0 = r1;
r1 = *(iterator.currentItem());
n = r1 - r0;
t = (p - r0)*n/(n*n);
if ( t > 1.0)
temp_d = (p - r1).length2();
else if ( t < 0.0)
temp_d = (p - r0).length2();
else
temp_d = (p - (r0 + t*n)).length2();
// ads_printf("temp_d = %lf\n", sqrt(temp_d));
if (temp_d < d)
d = temp_d;
}
return sqrt(d);
}
vec3
pline::first()
{
if (vertices.isEmpty())
get_points();
ListIterators<vec3> iterator(vertices);
iterator.reset();
return *(iterator.currentItem());
}
vec3
pline::last()
{
if (vertices.isEmpty())
get_points();
ListIterators<vec3> iterator(vertices);
vec3 last;
iterator.reset();
for (iterator.next(); !iterator.isDone(); iterator.next() )
{
last = *(iterator.currentItem());
}
return last;
}
void pline::Mark(const char * text, const char *layer, ads_real height)
{
if (vertices.isEmpty())
get_points();
ListIterators<vec3> iterator(vertices);
vec3 from, to, middle, dir;
int total = 0;
for (iterator.reset(); !iterator.isDone(); iterator.next() )
total++;
int count = 0;
for (iterator.reset() ; (count < (total/2 - 1 )); iterator.next() )
count++;
from = *(iterator.currentItem());
iterator.next();
to = *(iterator.currentItem());
dir = to - from;
middle = from + 0.5 * dir;
ads_point point = {middle[0], middle[1], middle[2]};
dir.normalize();
ads_real rotation = dir[VY] < 0 ? 6.28318530718 - acos(dir[VX])
: acos(dir[VX]);
struct resbuf *rb = ads_buildlist (RTDXF0, "TEXT",
8, layer, // layer
10, point, // insertion point
1, text,
40, height,
50, rotation,
62, 2, // color blue
0);
assert(rb != NULL);
int status = ads_entmake(rb);
assert(status == RTNORM);
ads_relrb(rb);
}
syntax highlighted by Code2HTML, v. 0.9.1