double vtIcoGlobe::AddSurfaceLineToMesh(vtGeomFactory *pMF, const DLine2 &line) { DPoint2 g1, g2; DPoint3 p1, p2; double scale = 1.0002; int length = 0; DMatrix3 rot3; pMF->PrimStart(); int i, j, size = line.GetSize(); for (i = 0; i < size-1; i++) { g1 = line.GetAt(i); g2 = line.GetAt(i+1); // for each pair of points, determine how many more points are needed // for a smooth arc geo_to_xyz(1.0, g1, p1); geo_to_xyz(1.0, g2, p2); double angle = acos(p1.Dot(p2)); int segments = (int) (angle * 2000); if (segments < 1) segments = 1; if (segments > 1) { // calculate the axis of rotation DPoint3 cross = p1.Cross(p2); cross.Normalize(); rot3.AxisAngle(cross, angle / segments); } // curved arc on great-circle path for (j = 0; j < segments; j++) { FPoint3 fp = p1 * 1.0002; pMF->AddVertex(fp); length++; if (j < segments-1) { rot3.Transform(p1, p2); p1 = p2; } } } // last vertex if (size > 1) { g2 = line.GetAt(size-1); geo_to_xyz(1.0, g2, p2); pMF->AddVertex(p2 * scale); length++; } pMF->PrimEnd(); return 0.0; }
void vtStructureArray::Offset(const DPoint2 &delta) { uint npoints = GetSize(); if (!npoints) return; uint i, j; DPoint2 temp; for (i = 0; i < npoints; i++) { vtStructure *str = GetAt(i); vtBuilding *bld = str->GetBuilding(); if (bld) bld->Offset(delta); vtFence *fen = str->GetFence(); if (fen) { DLine2 line = fen->GetFencePoints(); for (j = 0; j < line.GetSize(); j++) line.GetAt(j) += delta; } vtStructInstance *inst = str->GetInstance(); if (inst) inst->Offset(delta); } }
void vtLevel::SetFootprint(const DLine2 &dl) { // Safety check: Make sure there is at least an outer polygon if (m_Foot.size() == 0) m_Foot.resize(1); int prev = m_Foot[0].GetSize(); m_Foot[0] = dl; int curr = dl.GetSize(); if (curr != prev) RebuildEdges(curr); }
bool PolyChecker::IsSimplePolygon(const DLine2 &vertices) { int iSize = vertices.GetSize(); int i,j; for (i = 0; i < iSize - 2; i++) for (j = i + 2; j < (i == 0 ? iSize - 1 : iSize); j++) if (Intersect(vertices[i], vertices[(i + 1) % iSize], vertices[j], vertices[(j+ 1) % iSize])) return false; return true; }
bool PolyChecker::IsClockwisePolygon(const DLine2 &vertices) { DPoint2 p1, p2; int iSize = vertices.GetSize(); // Cannot remember if this works for all Jordan double Area = 0; for (int i = 0; i < iSize; i++) { p1 = vertices[i]; p2 = vertices[(i+1)%iSize]; Area += (p2.x - p1.x) * (p2.y + p1.y); } if (Area > 0) return true; else return false; }
/** * Create a set of points on the heightfield for a 2D polyline by draping the point onto * the surface. * * \param line The 2D line to drape, in Earth coordinates. * \param fSpacing The approximate spacing of the surface tessellation, used to * decide how finely to tessellate the line. * \param fOffset An offset to elevate each point in the resulting geometry, * useful for keeping it visibly above the ground. * \param bInterp True to interpolate between the vertices of the input * line. This is generally desirable when the ground is much more finely * spaced than the input line. * \param bCurve True to interpret the vertices of the input line as * control points of a curve. The created geometry will consist of * a draped line which passes through the control points. * \param bTrue True to use the true elevation of the terrain, ignoring * whatever scale factor is being used to exaggerate elevation for * display. * \param output Received the points. * \return The approximate length of the resulting 3D polyline. */ float vtHeightField3d::LineOnSurface(const DLine2 &line, float fSpacing, float fOffset, bool bInterp, bool bCurve, bool bTrue, FLine3 &output) { uint i, j; FPoint3 v1, v2, v; float fTotalLength = 0.0f; int iVerts = 0; uint points = line.GetSize(); if (bCurve) { DPoint2 p2, last(1E9,1E9); DPoint3 p3; int spline_points = 0; CubicSpline spline; for (i = 0; i < points; i++) { p2 = line[i]; if (i > 1 && p2 == last) continue; p3.Set(p2.x, p2.y, 0); spline.AddPoint(p3); spline_points++; last = p2; } spline.Generate(); // Estimate how many steps to subdivide this line into const double dLinearLength = line.Length(); float fLinearLength, dummy; m_LocalCS.VectorEarthToLocal(DPoint2(dLinearLength, 0.0), fLinearLength, dummy); double full = (double) (spline_points-1); int iSteps = (uint) (fLinearLength / fSpacing); if (iSteps < 3) iSteps = 3; double dStep = full / iSteps; FPoint3 last_v; for (double f = 0; f <= full; f += dStep) { spline.Interpolate(f, &p3); m_LocalCS.EarthToLocal(p3.x, p3.y, v.x, v.z); FindAltitudeAtPoint(v, v.y, bTrue); v.y += fOffset; output.Append(v); iVerts++; // keep a running total of approximate ground length if (f > 0) fTotalLength += (v - last_v).Length(); last_v = v; } } else { // not curved: straight line in earth coordinates FPoint3 last_v; for (i = 0; i < points; i++) { if (bInterp) { v1 = v2; m_LocalCS.EarthToLocal(line[i].x, line[i].y, v2.x, v2.z); if (i == 0) continue; // estimate how many steps to subdivide this segment into FPoint3 diff = v2 - v1; float fLen = diff.Length(); uint iSteps = (uint) (fLen / fSpacing); if (iSteps < 1) iSteps = 1; for (j = (i == 1 ? 0:1); j <= iSteps; j++) { // simple linear interpolation of the ground coordinate v.Set(v1.x + diff.x / iSteps * j, 0.0f, v1.z + diff.z / iSteps * j); FindAltitudeAtPoint(v, v.y, bTrue); v.y += fOffset; output.Append(v); iVerts++; // keep a running total of approximate ground length if (j > 0) fTotalLength += (v - last_v).Length(); last_v = v; } } else { m_LocalCS.EarthToLocal(line[i], v.x, v.z); FindAltitudeAtPoint(v, v.y, bTrue); v.y += fOffset; output.Append(v); } } } return fTotalLength; }
void vtVegLayer::AddElementsFromLULC(vtLULCFile *pLULC) { LULCSection *section; LULCPoly *poly; SetVegType(VLT_Density); //set projections vtProjection proj_new; proj_new.SetProjectionSimple(0, -1, EPSG_DATUM_WGS84); SetProjection(proj_new); // figure out the number of polygons in file uint size = 0; for (uint sec = 0; sec < pLULC->NumSections(); sec++) { section = pLULC->GetSection(sec); size = size + section->m_iNumPolys; } // Create density field m_field_density = m_pSet->AddField("Density", FT_Float); m_pSet->SetNumEntities(size); // get each poly from LULC file uint i, s, p, count = 0; float density=0; for (s = 0; s < pLULC->NumSections(); s++) { section = pLULC->GetSection(s); for (p = 0; p < section->m_iNumPolys; p++) { poly = section->m_pPoly + p; bool wild = false; switch (poly->Attribute) { case 42: // forest wild = true; density = 1.0f; break; case 32: case 33: wild = true; density = 0.5; break; case 22: // orchards wild = false; // no crops for now break; default: density = 0.0f; break; } DLine2 dline; dline.SetSize(poly->m_iCoords); // get Coords of LULCpoly and store as latlon, then save in VPoly for (i = 0; i < dline.GetSize(); i++) dline.SetAt(i, poly->m_p[i]); DPolygon2 dpoly; dpoly.push_back(dline); GetPS()->SetPolygon(count, dpoly); m_pSet->SetValue(count, m_field_density, density); count++; } } }