//! Implements <a href="http://qsar.sourceforge.net/dicts/blue-obelisk/index.xhtml#calculateOrthogonalisationMatrix">blue-obelisk:calculateOrthogonalisationMatrix</a> void OBUnitCell::SetData(const vector3 v1, const vector3 v2, const vector3 v3) { matrix3x3 m (v1, v2, v3); _mOrtho.FillOrth(vectorAngle(v2,v3), // alpha vectorAngle(v1,v3), // beta vectorAngle(v1,v2), // gamma v1.length(), // a v2.length(), // b v3.length()); // c _mOrient = m.transpose() * _mOrtho.inverse(); _spaceGroup = NULL; _spaceGroupName = ""; _lattice = OBUnitCell::Undefined; }
void WriteAngles(ostream &ofs,OBMol &mol) { // Alas, we still need to sort these to only list unique entries... vector3 v1, v2; OBAtom *a, *b, *c, *d; OBBond *bond1, *bond2, *bond3; vector<OBEdgeBase*>::iterator i, j, k; char buffer[BUFF_SIZE]; for (bond1 = mol.BeginBond(i); bond1; bond1 = mol.NextBond(i)) { b = bond1->GetBeginAtom(); c = bond1->GetEndAtom(); for (bond2 = b->BeginBond(j); bond2; bond2 = b->NextBond(j)) { if (bond2->GetEndAtomIdx() != c->GetIdx() && bond2->GetEndAtomIdx() != b->GetIdx()) { a = bond2->GetEndAtom(); v1 = a->GetVector() - b->GetVector(); v2 = c->GetVector() - b->GetVector(); sprintf(buffer,"%4d %4d %4d %4s %4s %4s %10.3f", a->GetIdx(),b->GetIdx(),c->GetIdx(), a->GetType(),b->GetType(),c->GetType(), vectorAngle(v1, v2)); ofs << buffer << endl; for (bond3 = c->BeginBond(k); bond3; bond3 = c->NextBond(k)) if (bond3->GetEndAtomIdx() != b->GetIdx() && bond3->GetEndAtomIdx() != c->GetIdx()) { d = bond3->GetEndAtom(); v1 = b->GetVector() - c->GetVector(); v2 = d->GetVector() - c->GetVector(); sprintf(buffer,"%4d %4d %4d %4s %4s %4s %10.3f", b->GetIdx(),c->GetIdx(),d->GetIdx(), b->GetType(),c->GetType(),d->GetType(), vectorAngle(v1, v2)); ofs << buffer << endl; } } } } }
inline static qreal signedAngle( const vec2 &v1, const vec2 &v2 ) { //assuming v1,v2 are normalized qreal a = vectorAngle( v1, v2 ); vec3 c = vec3::crossProduct( vec3(v1), vec3(v2) ); return c.z() > 0.0 ? a : -a; }
vector vectorCartesianToPolar(vector v) { double vAng = vectorAngle(v), vLength = vectorLength(v); v.x = vLength; v.y = vAng; return v; }
vector vectorLengthSet(vector v, double length) { double vAng; vAng = vectorAngle(v); v.x = length * cos(vAng); v.y = length * sin(vAng); return v; }
double CoordinateFrame::roll() const { // roll is the angle between the plane (world_up, cf_fwd) and the plane (cf_up, cf_fwd) // the angle between two planes is the angle between their normals // the normals are gotten with cross products // the vectorAngle function uses acos and dot product double roll = vectorAngle(cross(Vector3(0, 0, 1), fwd_), cross(up_, fwd_)); if(left_.z() < 0) roll = -roll; return roll; }
double OBUnitCell::GetGamma() const { return vectorAngle(_mOrtho.GetColumn(0), _mOrtho.GetColumn(1)); }
double OBUnitCell::GetAlpha() const { return vectorAngle(_mOrtho.GetColumn(1), _mOrtho.GetColumn(2)); }
vector vectorRotate(vector v, double ang) { double vAng; vAng = vectorAngle(v); return vectorAngleSet(v, ang + vAng); }
double vectorAngle(const GPoint & pt) { return vectorAngle(pt.getX(), pt.getY()); }
esvg::render::PointList esvg::render::Path::generateListPoints(int32_t _level, int32_t _recurtionMax, float _threshold) { ESVG_VERBOSE(spacingDist(_level) << "Generate List Points ... from a path"); esvg::render::PointList out; std::vector<esvg::render::Point> tmpListPoint; vec2 lastPosition(0.0f, 0.0f); vec2 lastAngle(0.0f, 0.0f); int32_t lastPointId = -1; bool PathStart = false; // Foreach element, we move in the path: for(auto &it : m_listElement) { if (it == nullptr) { continue; } ESVG_VERBOSE(spacingDist(_level+1) << " Draw : " << *it); switch (it->getType()) { case esvg::render::path_stop: if (tmpListPoint.size() != 0) { if (tmpListPoint.size() == 0) { ESVG_WARNING(spacingDist(_level+1) << " Request path stop of not starting path ..."); } else { tmpListPoint.back().setEndPath(); out.addList(tmpListPoint); tmpListPoint.clear(); } } lastAngle = vec2(0.0f, 0.0f); // nothing alse to do ... break; case esvg::render::path_close: if (tmpListPoint.size() != 0) { if (tmpListPoint.size() == 0) { ESVG_WARNING(spacingDist(_level+1) << " Request path close of not starting path ..."); } else { // find the previous tart of the path ... tmpListPoint.front().m_type = esvg::render::Point::type::join; // Remove the last point if it is the same position... vec2 delta = (tmpListPoint.front().m_pos - tmpListPoint.back().m_pos).absolute(); if ( delta.x() <= 0.00001 && delta.y() <= 0.00001) { tmpListPoint.pop_back(); ESVG_VERBOSE(" Remove point Z property : " << tmpListPoint.back().m_pos << " with delta=" << delta); } out.addList(tmpListPoint); tmpListPoint.clear(); } } lastAngle = vec2(0.0f, 0.0f); // nothing alse to do ... break; case esvg::render::path_moveTo: // stop last path if (tmpListPoint.size() != 0) { tmpListPoint.back().setEndPath(); out.addList(tmpListPoint); tmpListPoint.clear(); } // create a new one if (it->getRelative() == false) { lastPosition = vec2(0.0f, 0.0f); } lastPosition += it->getPos(); tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type::start)); lastAngle = lastPosition; break; case esvg::render::path_lineTo: // If no previous point, we need to create the last point has start ... if (tmpListPoint.size() == 0) { tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type::start)); } if (it->getRelative() == false) { lastPosition = vec2(0.0f, 0.0f); } lastPosition += it->getPos(); tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type::join)); lastAngle = lastPosition; break; case esvg::render::path_lineToH: // If no previous point, we need to create the last point has start ... if (tmpListPoint.size() == 0) { tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type::start)); } if (it->getRelative() == false) { lastPosition = vec2(0.0f, 0.0f); } lastPosition += it->getPos(); tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type::join)); lastAngle = lastPosition; break; case esvg::render::path_lineToV: // If no previous point, we need to create the last point has start ... if (tmpListPoint.size() == 0) { tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type::start)); } if (it->getRelative() == false) { lastPosition = vec2(0.0f, 0.0f); } lastPosition += it->getPos(); tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type::join)); lastAngle = lastPosition; break; case esvg::render::path_curveTo: // If no previous point, we need to create the last point has start ... if (tmpListPoint.size() == 0) { tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type::join)); } { vec2 lastPosStore(lastPosition); if (it->getRelative() == false) { lastPosition = vec2(0.0f, 0.0f); } vec2 pos1 = lastPosition + it->getPos1(); vec2 pos2 = lastPosition + it->getPos2(); vec2 pos = lastPosition + it->getPos(); interpolateCubicBezier(tmpListPoint, _recurtionMax, _threshold, lastPosStore, pos1, pos2, pos, 0, esvg::render::Point::type::join); lastPosition = pos; lastAngle = pos2; } break; case esvg::render::path_smoothCurveTo: // If no previous point, we need to create the last point has start ... if (tmpListPoint.size() == 0) { tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type::join)); } { vec2 lastPosStore(lastPosition); if (it->getRelative() == false) { lastPosition = vec2(0.0f, 0.0f); } vec2 pos2 = lastPosition + it->getPos2(); vec2 pos = lastPosition + it->getPos(); // generate Pos 1 vec2 pos1 = lastPosStore*2.0f - lastAngle; interpolateCubicBezier(tmpListPoint, _recurtionMax, _threshold, lastPosStore, pos1, pos2, pos, 0, esvg::render::Point::type::join); lastPosition = pos; lastAngle = pos2; } break; case esvg::render::path_bezierCurveTo: // If no previous point, we need to create the last point has start ... if (tmpListPoint.size() == 0) { tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type::join)); } { vec2 lastPosStore(lastPosition); if (it->getRelative() == false) { lastPosition = vec2(0.0f, 0.0f); } vec2 pos = lastPosition + it->getPos(); vec2 tmp1 = lastPosition + it->getPos1(); // generate pos1 and pos2 vec2 pos1 = lastPosStore + (tmp1 - lastPosStore)*0.666666666f; vec2 pos2 = pos + (tmp1 - pos)*0.666666666f; interpolateCubicBezier(tmpListPoint, _recurtionMax, _threshold, lastPosStore, pos1, pos2, pos, 0, esvg::render::Point::type::join); lastPosition = pos; lastAngle = tmp1; } break; case esvg::render::path_bezierSmoothCurveTo: // If no previous point, we need to create the last point has start ... if (tmpListPoint.size() == 0) { tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type::join)); } { vec2 lastPosStore(lastPosition); if (it->getRelative() == false) { lastPosition = vec2(0.0f, 0.0f); } vec2 pos = lastPosition + it->getPos(); vec2 tmp1 = lastPosStore*2.0f - lastAngle; // generate pos1 and pos2 vec2 pos1 = lastPosStore + (tmp1 - lastPosStore)*0.666666666f; vec2 pos2 = pos + (tmp1 - pos)*0.66666666f; interpolateCubicBezier(tmpListPoint, _recurtionMax, _threshold, lastPosStore, pos1, pos2, pos, 0, esvg::render::Point::type::join); lastPosition = pos; lastAngle = tmp1; } break; case esvg::render::path_elliptic: // If no previous point, we need to create the last point has start ... if (tmpListPoint.size() == 0) { tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type::join)); } { ememory::SharedPtr<esvg::render::ElementElliptic> tmpIt(ememory::dynamicPointerCast<esvg::render::ElementElliptic>(it)); float angle = tmpIt->m_angle * (M_PI / 180.0); ESVG_TODO(spacingDist(_level+1) << " Elliptic arc: radius=" << tmpIt->getPos1()); ESVG_TODO(spacingDist(_level+1) << " angle=" << tmpIt->m_angle); ESVG_TODO(spacingDist(_level+1) << " m_largeArcFlag=" << tmpIt->m_largeArcFlag); ESVG_TODO(spacingDist(_level+1) << " m_sweepFlag=" << tmpIt->m_sweepFlag); vec2 lastPosStore(lastPosition); if (it->getRelative() == false) { lastPosition = vec2(0.0f, 0.0f); } vec2 pos = lastPosition + it->getPos(); float rotationX = tmpIt->m_angle * (M_PI / 180.0); vec2 radius = tmpIt->getPos1(); #ifdef DEBUG m_debugInformation.addSegment(lastPosStore, pos); #endif vec2 delta = lastPosStore - pos; float ddd = delta.length(); if ( ddd < 1e-6f || radius.x() < 1e-6f || radius.y() < 1e-6f) { ESVG_WARNING("Degenerate arc in Line"); if (tmpListPoint.size() == 0) { tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type::join)); } tmpListPoint.push_back(esvg::render::Point(pos, esvg::render::Point::type::join)); } else { // Convert to center point parameterization. // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes // procedure describe here : http://www.w3.org/TR/SVG11/implnote.html#ArcConversionCenterToEndpoint // Compute delta' mat2 matrixRotationCenter = etk::mat2Rotate(-rotationX); vec2 deltaPrim = matrixRotationCenter * (delta*0.5f); ddd = (deltaPrim.x()*deltaPrim.x())/(radius.x()*radius.x()) + (deltaPrim.y()*deltaPrim.y())/(radius.y()*radius.y()); if (ddd > 1.0f) { #ifndef __STDCPP_LLVM__ ddd = std::sqrt(ddd); #else ddd = sqrtf(ddd); #endif radius *= ddd; } // Compute center' float sss = 0.0f; float ssa = radius.x()*radius.x()*radius.y()*radius.y() - radius.x()*radius.x()*deltaPrim.y()*deltaPrim.y() - radius.y()*radius.y()*deltaPrim.x()*deltaPrim.x(); float ssb = radius.x()*radius.x()*deltaPrim.y()*deltaPrim.y() + radius.y()*radius.y()*deltaPrim.x()*deltaPrim.x(); if (ssa < 0.0f) { ssa = 0.0f; } if (ssb > 0.0f) { #ifndef __STDCPP_LLVM__ sss = std::sqrt(ssa / ssb); #else sss = sqrtf(ssa / ssb); #endif } if (tmpIt->m_largeArcFlag == tmpIt->m_sweepFlag) { sss *= -1.0f; } vec2 centerPrime(sss * radius.x() * deltaPrim.y() / radius.y(), sss * -radius.y() * deltaPrim.x() / radius.x()); // Compute center from center' mat2 matrix = etk::mat2Rotate(rotationX); vec2 center = (lastPosStore + pos)*0.5f + matrix*centerPrime; #ifdef DEBUG m_debugInformation.addSegment(center-vec2(3.0,3.0), center+vec2(3.0,3.0)); m_debugInformation.addSegment(center-vec2(3.0,-3.0), center+vec2(3.0,-3.0)); #endif // Calculate theta1, and delta theta. vec2 vectorA = (deltaPrim - centerPrime) / radius; vec2 vectorB = (deltaPrim + centerPrime) / radius * -1.0f; #ifdef DEBUG m_debugInformation.addSegment(center, center+vectorA*radius.x()); m_debugInformation.addSegment(center, center+vectorB*radius.y()); #endif // Initial angle float theta1 = vectorAngle(vec2(1.0f,0.0f), vectorA); // Delta angle float deltaTheta = vectorAngle(vectorA, vectorB); // special case of invert angle... if ( ( deltaTheta == float(M_PI) || deltaTheta == -float(M_PI)) && tmpIt->m_sweepFlag == false) { deltaTheta *= -1.0f; } if (tmpIt->m_largeArcFlag == true) { // Choose large arc if (deltaTheta > 0.0f) { deltaTheta -= 2.0f*M_PI; } else { deltaTheta += 2.0f*M_PI; } } // Approximate the arc using cubic spline segments. matrix.translate(center); // Split arc into max 90 degree segments. // The loop assumes an iteration per end point (including start and end), this +1. #ifndef __STDCPP_LLVM__ int32_t ndivs = int32_t(std::abs(deltaTheta) / (M_PI*0.5f)) + 1; #else int32_t ndivs = int32_t(fabs(deltaTheta) / (M_PI*0.5f)) + 1; #endif float hda = (deltaTheta / float(ndivs)) * 0.5f; #ifndef __STDCPP_LLVM__ float kappa = std::abs(4.0f / 3.0f * (1.0f - std::cos(hda)) / std::sin(hda)); #else float kappa = fabs(4.0f / 3.0f * (1.0f - cosf(hda)) / sinf(hda)); #endif if (deltaTheta < 0.0f) { kappa = -kappa; } vec2 pointPosPrevious(0.0,0.0); vec2 tangentPrevious(0.0,0.0); for (int32_t iii=0; iii<=ndivs; ++iii) { float a = theta1 + deltaTheta * (float(iii)/(float)ndivs); #ifndef __STDCPP_LLVM__ delta = vec2(std::cos(a), std::sin(a)); #else delta = vec2(cosf(a), sinf(a)); #endif // position vec2 pointPos = matrix * vec2(delta.x()*radius.x(), delta.y()*radius.y()); // tangent vec2 tangent = matrix.applyScaleRotation(vec2(-delta.y()*radius.x() * kappa, delta.x()*radius.y() * kappa)); if (iii > 0) { vec2 zlastPosStore(lastPosition); if (it->getRelative() == false) { lastPosition = vec2(0.0f, 0.0f); } vec2 zpos1 = pointPosPrevious + tangentPrevious; vec2 zpos2 = pointPos - tangent; vec2 zpos = pointPos; interpolateCubicBezier(tmpListPoint, _recurtionMax, _threshold, zlastPosStore, zpos1, zpos2, zpos, 0, esvg::render::Point::type::join); lastPosition = zpos; lastAngle = zpos2; } pointPosPrevious = pointPos; tangentPrevious = tangent; } } lastPosition = pos; } break; default: ESVG_ERROR(spacingDist(_level+1) << " Unknow PATH commant (internal error)"); break; } } // special case : No request end of path ==> open path: if (tmpListPoint.size() != 0) { ESVG_VERBOSE("Auto-end PATH"); tmpListPoint.back().setEndPath(); out.addList(tmpListPoint); tmpListPoint.clear(); } out.display(); return out; }
// calculate height at (x,y) with plane float Terrain::getHeight (float x_float, float z_float, Angle &a) { Vector v1, v2, v3, normal, ab, bc; Plane plane; bool up; int res_int = (int) res; int x = (int) (x_float); int z = (int) (z_float); int xs, zs; xs = (int) ((x+size/2) / res_int) * res_int - (size/2); zs = (int) ((z+size/2) / res_int) * res_int - (size/2); // FIND PLANE EQUATION (Ax + By + Cz + D) // find triangle - START // mi servono i vertici della diagonale -> 0 e 2 v1.x = xs; v1.z = zs; v1.y = getHeightFromMap (v1.x+size/2, v1.z+size/2); v3.x = xs + res; v3.z = zs + res; v3.y = getHeightFromMap (v3.x+size/2, v3.z+size/2); // calcolo la retta passante per i punti float rect_z = v3.z * ((xs-v1.x)/(v3.x-v1.x)); if (z_float > rect_z) up = true; else up = false; // find triangle - END if (up) { v2.x = xs; v2.z = zs + res; v2.y = getHeightFromMap (v2.x+size/2, v2.z+size/2); } else { v2.x = xs + res; v2.z = zs; v2.y = getHeightFromMap (v2.x+size/2, v2.z+size/2); } // calculate plane equation vectorSubtract (v1, v2, ab); vectorSubtract (v2, v3, bc); crossProduct (ab, bc, normal); makePlane (v1, normal, plane); // calculate height float height = (plane.d - (plane.a * x_float) - (plane.c * z_float)) / plane.b; // calculate angle x Vector temp_vec; temp_vec.x = 1.0; temp_vec.y = 0.0; temp_vec.z = 0.0; float temp_angle_x = vectorAngle (temp_vec, normal); a.x = 90.0 - temp_angle_x; // calculate angle z temp_vec.x = 0.0; temp_vec.y = 0.0; temp_vec.z = 1.0; float temp_angle_z = vectorAngle (temp_vec, normal); a.z = 90.0 - temp_angle_z; // return height return height; }