Vec2d ParametricCubic::CalcGradient( double t ) const { double dx = m_x.CalcGradient(t); double dy = m_y.CalcGradient(t); return Vec2d(dx, dy); }
Explosion::Explosion(Vec3d &position, GLfloat scale, Vec2d damageRange) : Entity(game->getAnimationManager()->get("fireball"), position, Vec2d(scale, scale)) { setSize(int(scale)); mLifeTimer.start(); game->getSoundEngine()->play3DSound(game->getResourceManager()->get("grenade_explode"),mPosition, 2.0f * scale, randomFloat(0.75, 1.25)); mDamageRange = damageRange; mDamage = -1; }
Vec2d ParametricCubic::Calc( double t ) const { double x = m_x.CalcY(t); double y = m_y.CalcY(t); return Vec2d(x, y); }
Vec2d Delta () const { return Vec2d (p2.X()-p1.X(), p2.Y()-p1.Y()); }
inline Vec2d operator- (const Point2d & p1, const Point2d & p2) { return Vec2d (p1.X() - p2.X(), p1.Y() - p2.Y()); }
void WorkerBee::onState(State state, sf::Time dt) { Vec2d empty(-1.0, -1.0); // first state if (state == IN_HIVE) { // if bee has pollen transfer it to hive if (getPollen() > 0) { transferPollen(dt); flower_location_ = empty; setDebugStatus("in_hive_leaving_pollen"); } else { // if bee has not enough energy to leave hive, eat its nectar if (getEnergy() < energy_leave_hive_ && getHive().getNectar() > 0) { setDebugStatus("in_hive_eating"); eatFromHive(dt); } // if there is a flower in memory and enough energy, target move // to this flower else if (flower_location_ != empty && getEnergy() > energy_collect_pollen_) { setDebugStatus("in_hive_leaving"); setMoveTarget(flower_location_); // change state to to flower nextState(); } else { setDebugStatus("in_hive_no_flower"); } } } // second state else if (state == TO_FLOWER) { setDebugStatus("to_flower"); if (getEnergy() < energy_collect_pollen_) { nextState(); nextState(); } Flower* flower = getAppEnv().getCollidingFlower(getVisionRange()); if (flower) { setMoveTarget(flower->getPosition()); setMoveState(MoveState::TARGET); if (isPointInside(flower->getPosition())) { nextState(); } } else if (isPointInside(flower_location_)) { // go back to hive and clear location nextState(); nextState(); setFlowerLocation(Vec2d(-1,-1)); } } // third state else if (state == COLLECT_POLLEN) { // if there is a flower at flower location and it has pollen and // bee has not enough pollen, eat pollen from flower Flower* flower(getAppEnv().getCollidingFlower(getCollider())); if ((getPollen() < max_pollen_) && (flower != nullptr) && (flower->getPollen() > 0)) { eatPollen(flower, dt); } else { // else skip collection nextState(); } } else if (state == RETURN_HIVE) { // if bee is in hive change state to in hive if (getHive().isColliderInside(getCollider())) { nextState(); } } }
void PSSMLTRenderer::SampleAndEvaluatePath( const std::shared_ptr<Sampler>& sampler, PathSampleRecord& record ) { Ray ray; Intersection isect; Vec3d throughput(1.0); int depth = 0; Vec3d L; // Raster position Vec2d rasterPos(sampler->Next(), sampler->Next()); record.pixelPos.x = (int)(rasterPos.x * config->width); record.pixelPos.y = (int)(rasterPos.y * config->height); // Generate ray double _; scene->Camera()->SampleAndEvaluate(rasterPos, ray, _); // ---------------------------------------------------------------------- // Initial intersection if (!scene->Intersect(ray, isect)) { record.L = L; record.I = RenderUtils::Luminance(L); return; } if (isect.primitive->Light() != nullptr) { auto& light = isect.primitive->Light(); L += light->Evaluate(-ray.d, isect.gn); } // ---------------------------------------------------------------------- while (true) { auto& bsdf = isect.primitive->Bsdf(); // Explicit (direct) light sampling // We do not handle the light path with length 1 (EL path) if (isect.primitive != nullptr) { auto positionSample = Vec2d(sampler->Next(), sampler->Next()); // Sample a light std::shared_ptr<AreaLight> light; double lightSelectionPdf; scene->SampleLight(positionSample.x, light, lightSelectionPdf); // Sample a position on the light AreaLight::SampleRecord lightSampleRec; lightSampleRec.positionSample = positionSample; light->SamplePosition(lightSampleRec); // Check visibility Ray shadowRay; auto d = lightSampleRec.p - isect.p; shadowRay.d = Math::Normalize(d); shadowRay.o = isect.p; shadowRay.minT = isect.rayEpsilon; shadowRay.maxT = Math::Length(d) * (1.0 - Eps); Intersection shadowIsect; if (!scene->Intersect(shadowRay, shadowIsect)) { // Evaluate Le (with cosine term) auto Le = light->EvaluateCos(-shadowRay.d, lightSampleRec.n) / lightSelectionPdf; // Convert to Le / p_\sigma auto dist2 = Math::Length2(d); Le /= Vec3d(dist2); // Prepare for BSDF evaluation BSDFRecord bsdfRec; bsdfRec.type = BSDFType::All; bsdfRec.adjoint = false; bsdfRec.wi = isect.worldToShading * -ray.d; bsdfRec.wo = isect.worldToShading * shadowRay.d; // Evaluate BSDF (with cosine term) auto f = bsdf->Evaluate(bsdfRec, isect); if (f != Vec3d()) { // Calculate PDF for light and BSDF (in solid angle measure) double dDotN = Math::Dot(-shadowRay.d, lightSampleRec.n); double lightPdf = dDotN <= 0 ? 0.0 : lightSelectionPdf * // Selection lightSampleRec.pdf * // p_A(x_n) dist2 / dDotN; // Convert to p_\sigma(x_{n-1}\to x_n) if (lightPdf > 0) { // It should be positive double bsdfPdf = bsdf->Pdf(bsdfRec); // MIS weight (for direct light sampling) double w = lightPdf / (lightPdf + bsdfPdf); // Record color L += throughput * f * Le * w; } } } } // ---------------------------------------------------------------------- // BSDF sampling BSDFSample bsdfSample; bsdfSample.u = Vec2d(sampler->Next(), sampler->Next()); bsdfSample.uComponent = sampler->Next(); BSDFRecord bsdfRec; bsdfRec.type = BSDFType::All; bsdfRec.adjoint = false; bsdfRec.wi = isect.worldToShading * -ray.d; double bsdfPdf; auto f = bsdf->SampleAndEvaluate(bsdfRec, bsdfSample, bsdfPdf, isect); if (bsdfPdf == 0.0 || f == Vec3d()) { record.L = L; record.I = RenderUtils::Luminance(L); return; } // Convert to world coordinates bsdfRec.wo = isect.shadingToWorld * bsdfRec.wo; // Update throughput throughput *= f; // Setup next ray ray.d = bsdfRec.wo; ray.o = isect.p; ray.minT = isect.rayEpsilon; ray.maxT = Inf; // ---------------------------------------------------------------------- // Check intersection if (!scene->Intersect(ray, isect)) { record.L = L; record.I = RenderUtils::Luminance(L); return; } auto light = isect.primitive->Light(); if (light != nullptr) { // Intersected with L // Evaluate Le auto Le = light->Evaluate(-ray.d, isect.gn); if ((bsdfRec.sampledType & BSDFType::Delta) != 0) { // Disable MIS if last intersection is specular interaction L += throughput * Le; } else { // Calculate PDF for light (in solid angle measure) double dist2 = Math::Length2(ray.o - isect.p); double dDotN = Math::Dot(-ray.d, isect.gn); double lightPdf = dDotN <= 0 ? 0.0 : scene->LightSelectionPdf() * // Selection light->PdfPosition() * // p_A(x_n) dist2 / dDotN; // Convert to p_\sigma(x_{n-1}\to x_n) // MIS weight (for BSDF sampling) double w = bsdfPdf / (lightPdf + bsdfPdf); // Record color L += throughput * Le * w; } } // ---------------------------------------------------------------------- if (++depth >= config->rrDepth) { // Russian roulette for path termination double p = Math::Min(0.5, RenderUtils::Luminance(throughput)); if (sampler->Next() > p) { break; } throughput /= Vec3d(p); } } record.L = L; record.I = RenderUtils::Luminance(L); }
std::vector<Vec2d> Tangents(const Arc &arc) { auto radius_inv = (1.f/arc.circle.radius); auto d0 = (arc.endpoints.pts[0] - arc.circle.center) * radius_inv; auto d1 = (arc.endpoints.pts[1] - arc.circle.center) * radius_inv; return {Vec2d(-d0[1], d0[0]), Vec2d(-d1[1], d1[0])}; }
void SwampMonster::attack() { Vec3d playerPos = game->getPlayer()->getPosition() - mPosition; //Vec2d angle(atan2(playerPos.X-mPosition.X, playerPos.Z-mPosition.Z)); playerPos.normalize(); playerPos /= 8; //range.setLength(1.0); game->getEntityManager()->add(New Projectile(mPosition,playerPos,game->getAnimationManager()->get("fireball"),Vec2d(5,10),ENTITY_ATTACK_ENEMY)); speak(getAttackSound()); game->getSoundEngine()->play3DSound(game->getResourceManager()->get("flame_attack"),mPosition); }
void Enemy::onUpdate() { if(invisibility) invisibility--; Vec2i facing = intToDir(dir); if(level.getAIFlags(position) & 2) { // Vergiftung contamination--; } if(contamination <= 0) burst(); if(!thinkCounter--) { // den nächsten Spieler suchen, der für den Gegner sichtbar ist Player* p_closestPlayer = 0; int closestDist = 0; const std::list<Player*>& players = Player::getInstances(); for(std::list<Player*>::const_iterator i = players.begin(); i != players.end(); ++i) { if(!(*i)->isTeleporting()) { int dist = (position - (*i)->getPosition()).lengthSq(); if(dist < closestDist || !p_closestPlayer) { if(canSee((*i)->getPosition())) { p_closestPlayer = *i; closestDist = dist; } } } } if(p_closestPlayer) { targetPosition = p_closestPlayer->getPosition(); interest += 2225 - closestDist; } thinkCounter = random(2, 5); } if(subType == 0) { int oldDir = dir; if(moveCounter-- <= 0 && fabs(shownDir - dir) < 0.4) { int r = random(0, 8); if(interest >= 10000) r = random(0, 40); if(contamination < 50) { if(random() % 2) r = 0; } interest /= 2; switch(r) { case 0: { int d = random(-22, 22) / 10; if(d) dir += d, anim += 16; } break; case 1: case 2: case 3: if(!tryToMove(facing)) dir += random(-22, 22) / 10; anim += 16; break; default: if(r >= 6 && targetPosition.x != -1) { // zum Ziel laufen Vec2i toTarget = targetPosition - position; if(toTarget.x && toTarget.y) toTarget.value[random(0, 1)] = 0; int d = dirToInt(toTarget); toTarget = intToDir(d); if(tryToMove(toTarget)) { dir = d; anim += 16; interest *= 2; } } break; } if(position == targetPosition || interest < 10) { targetPosition = Vec2i(-1, -1); interest = 0; } while(dir < 0) dir += 4, shownDir += 4.0; dir %= 4; moveCounter = random(4, 7); } if(anim) anim--; double dd = static_cast<double>(dir) - shownDir; if(dd > 2.0) shownDir += 4.0; else if(dd < -2.0) shownDir -= 4.0; shownDir = 0.125 * dir + 0.875 * shownDir; if(!soundCounter) { if(oldDir != dir) { // Kratz-Sound abspielen Engine::inst().playSound("enemy1_turn.ogg", false, 0.1, -100); soundCounter = random(15, 55); } } else soundCounter--; if(burpCounter) { burpCounter--; if(!burpCounter) { int s = random(0, 1); std::string sound; if(s == 0) sound = "enemy1_burp1.ogg"; else if(s == 1) sound = "enemy1_burp2.ogg"; Engine::inst().playSound(sound, false, 0.1); // Rülpspartikel erzeugen ParticleSystem* p_particleSystem = level.getParticleSystem(); ParticleSystem::Particle p; for(int i = 0; i < 10; i++) { p.lifetime = random(50, 75); p.damping = 0.99f; p.gravity = random(-0.005f, -0.02f); p.positionOnTexture = Vec2b(96, 32); p.sizeOnTexture = Vec2b(16, 16); p.position = position * 16 + Vec2i(8 + random(-4, 4), 6); p.velocity = Vec2d(random(-0.5, 0.5), random(-1.0, -0.5)); p.color = Vec4d(random(0.8, 1.0), random(0.8, 1.0), random(0.8, 1.0), 0.25); p.deltaColor = Vec4d(0.0, 0.0, 0.0, -p.color.a / p.lifetime); p.rotation = random(-0.5f, 0.5f); p.deltaRotation = random(-0.05f, 0.05f); p.size = random(0.2f, 1.0f); p.deltaSize = random(0.0f, 0.01f); p_particleSystem->addParticle(p); } } } } else if(subType == 1) { if(random() % 2) anim++; if(moveCounter-- <= 0) { int r = random(0, 1); if(interest > 6000) r = random(0, 50); if(contamination < 50) { if(random() % 2) r = 0; } interest /= 2; switch(r) { case 0: tryToMove(intToDir(random(0, 4))); break; default: if(targetPosition.x != -1) { // zum Ziel laufen Vec2i toTarget = targetPosition - position; if(toTarget.x && toTarget.y) toTarget.value[random(0, 1)] = 0; int d = dirToInt(toTarget); toTarget = intToDir(d); if(tryToMove(toTarget)) interest *= 2; } else { // Wo ist die Spur am heißesten? int bestDir = 0; uint bestTrace = 0; for(int dir = 0; dir < 4; dir++) { uint trace = level.getAITrace(position + intToDir(dir)); if(trace > bestTrace) { bestTrace = trace; bestDir = dir; } } if(bestTrace) { Vec2i bestDirV = intToDir(bestDir); if(!tryToMove(bestDirV)) { // Das ging nicht. Ist da ein anderer Gegner? bool reduceTrace = true; Object* p_obj = level.getFrontObjectAt(position + bestDirV); if(p_obj) { // Wenn da ein anderer Gegner ist, ist es egal. if(p_obj->getType() == "Enemy") reduceTrace = false; } if(reduceTrace) { // Die Spur dort etwas uninteressanter machen! level.setAITrace(position + bestDirV, bestTrace / 2); } } else { if(bestTrace > 850) interest = 160000; else if(bestTrace > 100) interest = 20000; } } } break; } if(position == targetPosition || interest < 10) { targetPosition = Vec2i(-1, -1); interest = 0; } moveCounter = random(4, 7); } if(height == 0.0) { if(!(random() % 25)) { vy = random(40.0, 80.0); height = 0.5; } } else { height += 0.02 * vy; vy -= 0.02 * 400.0; if(height < 0.5) { height = 0.0; vy = 0.0; } } int pr = 700; if(interest >= 10000) pr = 350; if(!(random() % pr)) { // Lachen abspielen Engine::inst().playSound("enemy2_laugh.ogg", false, 0.15, -100); } if(interest >= 40000) { if(!(random() % 200)) { // Knurren abspielen Engine::inst().playSound("enemy2_growl.ogg", false, 0.15, -100); } } if(interest >= 10000) { // Feuer ParticleSystem* p_particleSystem = level.getParticleSystem(); ParticleSystem* p_fireParticleSystem = level.getFireParticleSystem(); ParticleSystem::Particle p; p.lifetime = random(40, 50); p.damping = 0.9f; p.gravity = -0.04f; p.positionOnTexture = Vec2b(32, 0); p.sizeOnTexture = Vec2b(16, 16); const double r = random(0.0, 6.283); const Vec2d vr(sin(r), cos(r)); p.position = position * 16 + Vec2d(7.5, 7.5 - height) + 7.5 * vr; p.velocity = vr; p.color = Vec4d(random(0.5, 1.0), random(0.8, 1.0), random(0.0, 0.25), random(0.2, 0.4)); const double dc = -1.5 / (p.lifetime + random(-25, 25)); p.deltaColor = Vec4d(dc, dc, dc, -p.color.a / p.lifetime); p.rotation = random(0.0f, 10.0f); p.deltaRotation = random(-0.1f, 0.1f); p.size = random(0.5f, 0.9f); p.deltaSize = random(0.0075f, 0.015f); if(random() % 2) p_particleSystem->addParticle(p); else p_fireParticleSystem->addParticle(p); } } if(eatCounter) eatCounter--; }
void SimUIForm::FingerHandler::EnterSelect(Event *pevt) { // Leave current modes EnterNone(); // Form a box around the two down points Rect rc; if (m_x1 < m_x2) { rc.left = m_x1; rc.right = m_x2; } else { rc.left = m_x2; rc.right = m_x1; } if (m_y1 < m_y2) { rc.top = m_y1; rc.bottom = m_y2; } else { rc.top = m_y2; rc.bottom = m_y1; } // Initialize the drag rect. It expects a bottom left coordinate // system. If the rect is rotated 90 cw, then it fits SimUI's // coordinate system if x/y are swapped. DPoint pt0, pt1, pt2; pt0.x = rc.top; pt0.y = rc.left; pt1.x = rc.bottom; pt1.y = rc.left; pt2.x = rc.bottom; pt2.y = rc.right; DragRect drc; drc.Init(pt0, pt1, pt2); // Figure out the tracking masks #define kcpCloseEnough 32.0 DPoint ptA; ptA.x = m_y1; ptA.y = m_x1; m_maskA = drc.HitTest(ptA, &m_vOffsetA); if (m_vOffsetA.mag() > kcpCloseEnough) { m_vOffsetA = Vec2d(0, 0); } DPoint ptB; ptB.x = m_y2; ptB.y = m_x2; m_maskB = drc.HitTest(ptB, &m_vOffsetB); if (m_vOffsetB.mag() > kcpCloseEnough) { m_vOffsetB = Vec2d(0, 0); } // Show the drag rect m_pselspr->SetDragRect(drc); m_pselspr->Show(true); // Redraw the screen so the selection updates gevm.SetRedrawFlags(kfRedrawDirty | kfRedrawBeforeTimer); // Set selection based on this rect SetSelection(); // Enter FHS_SELECT mode m_state = FHS_SELECT; }
void Enemy::onCollect(Player* p_player) { if(p_player->isTeleporting()) return; if(subType == 0) { if(!eatCounter) { ParticleSystem* p_particleSystem = level.getParticleSystem(); ParticleSystem::Particle p; // die Metzelei hinter einer Staubwolke verstecken for(int i = 0; i < 150; i++) { p.lifetime = 100; p.damping = 0.99f; p.gravity = 0.005f; p.positionOnTexture = Vec2b(0, 0); p.sizeOnTexture = Vec2b(16, 16); p.position = position * 16 + Vec2i(random(4, 12), random(4, 12)); double a = random(0.0, 1000.0); p.velocity = Vec2d(sin(a), cos(a)) * random(0.05, 1.0); double c = random(0.6, 1.0); p.color = p_player->getDebrisColor(); p.color.a *= random(0.5f, 1.2f); p.deltaColor = Vec4d(0.0, 0.0, 0.0, -p.color.a / p.lifetime); p.rotation = random(0.0f, 10.0f); p.deltaRotation = random(-0.1f, 0.1f); p.size = random(0.3f, 0.5f); p.deltaSize = random(0.01f, 0.05f); p_particleSystem->addParticle(p); } Engine::inst().playSound("enemy1_eat.ogg", false, 0.1); p_player->disappear(1.5); p_player->censored = true; moveCounter = 130; eatCounter = 130; burpCounter = 100; slideDir = -1; } } else if(subType == 1) { if(!eatCounter) { ParticleSystem* p_particleSystem = level.getParticleSystem(); ParticleSystem::Particle p; // die Metzelei hinter einer Staubwolke verstecken for(int i = 0; i < 150; i++) { p.lifetime = 100; p.damping = 0.99f; p.gravity = 0.005f; p.positionOnTexture = Vec2b(0, 0); p.sizeOnTexture = Vec2b(16, 16); p.position = position * 16 + Vec2i(random(4, 12), random(4, 12)); double a = random(0.0, 1000.0); p.velocity = Vec2d(sin(a), cos(a)) * random(0.05, 1.0); double c = random(0.6, 1.0); p.color = p_player->getDebrisColor(); p.color.a *= random(0.5f, 1.2f); p.deltaColor = Vec4d(0.0, 0.0, 0.0, -p.color.a / p.lifetime); p.rotation = random(0.0f, 10.0f); p.deltaRotation = random(-0.1f, 0.1f); p.size = random(0.3f, 0.5f); p.deltaSize = random(0.01f, 0.05f); p_particleSystem->addParticle(p); } Engine::inst().playSound("enemy2_eat.ogg", false, 0.1); p_player->disappear(1.5); p_player->censored = true; moveCounter = 130; eatCounter = 130; burpCounter = 100; slideDir = -1; } } }
Range2<double> Range2<double>::Empty() { return Range2<double>(Vec2d(DBL_MAX, DBL_MAX), Vec2d(-DBL_MAX, -DBL_MAX)); }
Sprite::Sprite(Texture *texture) { mpTexture = texture; mScale = Vec2d(1,1); mSize = Vec2d(mpTexture->getWidth(), mpTexture->getHeight()); }
void Monster::think(const double elapsedTime) { Entity::think(elapsedTime); if(!mIsDying && mHealth <= 0) kill(); if(mIsStunned) { if(mPosition.Y > -0.5) { mVelocity.Y -= 0.005; mPosition += mVelocity; if(game->getCurrentMap()->getTile(int(mPosition.X + mVelocity.X), int(mPosition.Z)).type == TYPE_WALL) { mVelocity.X = -mVelocity.X; mVelocity *= MONSTER_DAMPING; } if(game->getCurrentMap()->getTile(int(mPosition.X), int(mPosition.Z + mVelocity.Z)).type == TYPE_WALL) { mVelocity.Z = -mVelocity.Z; mVelocity *= MONSTER_DAMPING; } } else { mIsStunned = false; mPosition.Y = -0.5; } } if(mIsDying) { if(mDeathTimer.getElapsedTime() >= 500) mShouldDelete = true; return; } if(mIsFrozen) { if(mFreezeTimer.getElapsedTime() < 5000) { return; } else setFrozen(false); } if(mIsFleeing) { Vec2d motion = Vec2d(playerPos.X-mPosition.X,playerPos.Z-mPosition.Z); motion.normalize(); motion /= 35; if((playerPos.X - mPosition.X) + (playerPos.Z - mPosition.Z) < 0.3) { int goalStr = game->getCurrentMap()->getTile(int(mPosition.X), int(mPosition.Z)).goodCreatureGoal; playerPos = mPosition; for(int i = -1; i < 2; ++i) for(int j = -1; j < 2; ++j) if(game->getCurrentMap()->getTile(i + int(mPosition.X), j + int(mPosition.Z)).type != TYPE_WALL && goalStr < game->getCurrentMap()->getTile(i + int(mPosition.X), j + int(mPosition.Z)).goodCreatureGoal && game->getCurrentMap()->getTile(i + int(mPosition.X), j + int(mPosition.Z)).goodCreatureGoal < 100) { goalStr = game->getCurrentMap()->getTile(i + int(mPosition.X), j + int(mPosition.Z)).goodCreatureGoal; playerPos.X = mPosition.X + i; playerPos.Z = mPosition.Z + j; } } game->getCurrentMap()->setGoal(int(playerPos.X), int(playerPos.Z), 0); game->getCurrentMap()->setGoal(int(mPosition.X), int(mPosition.Z), 0); //Increase position of monster. mPosition -= Vec3d(motion.X(),0,motion.Y()); } else { Vec2d motion = Vec2d(playerPos.X-mPosition.X,playerPos.Z-mPosition.Z); motion.normalize(); motion /= 50; if((playerPos.X - mPosition.X) + (playerPos.Z - mPosition.Z) < 0.3) { int goalStr = game->getCurrentMap()->getTile(int(mPosition.X), int(mPosition.Z)).goodCreatureGoal; playerPos = mPosition; for(int i = -1; i < 2; ++i) for(int j = -1; j < 2; ++j) if(game->getCurrentMap()->getTile(i + int(mPosition.X), j + int(mPosition.Z)).type != TYPE_WALL && goalStr < game->getCurrentMap()->getTile(i + int(mPosition.X), j + int(mPosition.Z)).goodCreatureGoal && game->getCurrentMap()->getTile(i + int(mPosition.X), j + int(mPosition.Z)).goodCreatureGoal < 100) { goalStr = game->getCurrentMap()->getTile(i + int(mPosition.X), j + int(mPosition.Z)).goodCreatureGoal; playerPos.X = mPosition.X + i; playerPos.Z = mPosition.Z + j; } } game->getCurrentMap()->setGoal(int(playerPos.X), int(playerPos.Z), 0); game->getCurrentMap()->setGoal(int(mPosition.X), int(mPosition.Z), 0); //Increase position of monster. mPosition += Vec3d(motion.X(),0,motion.Y()); } /*if(rand() % 500 == 0) { attack(); } if(rand() % 5000 == 0) { makeMonsterNoise(); }*/ if(mVoice) mVoice->setPosition(mPosition); }
// Called from the constructor. // Set the initial bed shape from a list of points. // Deduce the bed shape type(rect, circle, custom) // This routine shall be smart enough if the user messes up // with the list of points in the ini file directly. void BedShapePanel::set_shape(ConfigOptionPoints* points) { auto polygon = Polygon::new_scale(points->values); // is this a rectangle ? if (points->size() == 4) { auto lines = polygon.lines(); if (lines[0].parallel_to(lines[2]) && lines[1].parallel_to(lines[3])) { // okay, it's a rectangle // find origin coordf_t x_min, x_max, y_min, y_max; x_max = x_min = points->values[0](0); y_max = y_min = points->values[0](1); for (auto pt : points->values) { x_min = std::min(x_min, pt(0)); x_max = std::max(x_max, pt(0)); y_min = std::min(y_min, pt(1)); y_max = std::max(y_max, pt(1)); } auto origin = new ConfigOptionPoints{ Vec2d(-x_min, -y_min) }; m_shape_options_book->SetSelection(SHAPE_RECTANGULAR); auto optgroup = m_optgroups[SHAPE_RECTANGULAR]; optgroup->set_value("rect_size", new ConfigOptionPoints{ Vec2d(x_max - x_min, y_max - y_min) });//[x_max - x_min, y_max - y_min]); optgroup->set_value("rect_origin", origin); update_shape(); return; } } // is this a circle ? { // Analyze the array of points.Do they reside on a circle ? auto center = polygon.bounding_box().center(); std::vector<double> vertex_distances; double avg_dist = 0; for (auto pt: polygon.points) { double distance = (pt - center).cast<double>().norm(); vertex_distances.push_back(distance); avg_dist += distance; } avg_dist /= vertex_distances.size(); bool defined_value = true; for (auto el: vertex_distances) { if (abs(el - avg_dist) > 10 * SCALED_EPSILON) defined_value = false; break; } if (defined_value) { // all vertices are equidistant to center m_shape_options_book->SetSelection(SHAPE_CIRCULAR); auto optgroup = m_optgroups[SHAPE_CIRCULAR]; boost::any ret = wxNumberFormatter::ToString(unscale<double>(avg_dist * 2), 0); optgroup->set_value("diameter", ret); update_shape(); return; } } if (points->size() < 3) { // Invalid polygon.Revert to default bed dimensions. m_shape_options_book->SetSelection(SHAPE_RECTANGULAR); auto optgroup = m_optgroups[SHAPE_RECTANGULAR]; optgroup->set_value("rect_size", new ConfigOptionPoints{ Vec2d(200, 200) }); optgroup->set_value("rect_origin", new ConfigOptionPoints{ Vec2d(0, 0) }); update_shape(); return; } // This is a custom bed shape, use the polygon provided. m_shape_options_book->SetSelection(SHAPE_CUSTOM); // Copy the polygon to the canvas, make a copy of the array. m_canvas->m_bed_shape = points->values; update_shape(); }
void Curve::computeCurvatureAndOrientation () { const_vertex_iterator v = vertices_begin(), vend = vertices_end(), v2, prevV, v0; Vec2d p0, p1, p2; Vec3r p; p = (*v)->point2d(); p0 = Vec2d(p[0], p[1]); prevV = v; ++v; p = (*v)->point2d(); p1 = Vec2d(p[0], p[1]); Vec2d prevDir(p1 - p0); for (; v! = vend; ++v) { v2 = v; ++v2; if (v2 == vend) break; Vec3r p2 = (*v2)->point2d(); Vec2d BA = p0 - p1; Vec2d BC = p2 - p1; real lba = BA.norm(), lbc = BC.norm(); BA.normalizeSafe(); BC.normalizeSafe(); Vec2d normalCurvature = BA + BC; Vec2d dir = Vec2d(BC - BA); Vec2d normal = Vec2d(-dir[1], dir[0]); normal.normalizeSafe(); real curvature = normalCurvature * normal; if (lba + lbc > MY_EPSILON) curvature /= (0.5 * lba + lbc); if (dir.norm() < MY_EPSILON) dir = 0.1 * prevDir; (*v)->setCurvatureFredo(curvature); (*v)->setDirectionFredo(dir); prevV = v; p0 = p1; p1 = p2; prevDir = dir; prevDir.normalize(); } (*v)->setCurvatureFredo((*prevV)->curvatureFredo()); (*v)->setDirectionFredo((*v)->point2d() - (*prevV)->point2d()); v0 = vertices_begin(); v2 = v0; ++v2; (*v0)->setCurvatureFredo((*v2)->curvatureFredo()); (*v0)->setDirectionFredo((*v2)->point2d() - (*v0)->point2d()); //closed curve case one day... // return; //numerical degeneracy verification... we'll see later const_vertex_iterator vLastReliable = vertices_begin(); v = vertices_begin(); p = (*v)->point2d(); p0 = Vec2d(p[0], p[1]); prevV = v; ++v; p = (*v)->point2d(); p1 = Vec2d(p[0], p[1]); bool isReliable = false; if ((p1 - p0).norm > EPS_CURVA) { vLastReliable = v; isReliable = true; } for (; v != vend; ++v) { v2 = v; ++v2; if (v2 == vend) break; Vec3r p2 = (*v2)->point2d(); Vec2d BA = p0 - p1; Vec2d BC = p2 - p1; real lba = BA.norm(), lbc = BC.norm(); if ((lba + lbc) < EPS_CURVA) { isReliable = false; cerr << "/"; } else { if (!isReliable) { //previous points were not reliable const_vertex_iterator vfix = vLastReliable; ++vfix; for (; vfix != v; ++vfix) { (*vfix)->setCurvatureFredo((*v)->curvatureFredo()); (*vfix)->setDirectionFredo((*v)->directionFredo()); } } isReliable = true; vLastReliable = v; } prevV = v; p0 = p1; p1 = p2; } }
// Update the bed shape from the dialog fields. void BedShapePanel::update_shape() { auto page_idx = m_shape_options_book->GetSelection(); if (page_idx == SHAPE_RECTANGULAR) { Vec2d rect_size(Vec2d::Zero()); Vec2d rect_origin(Vec2d::Zero()); try{ rect_size = boost::any_cast<Vec2d>(m_optgroups[SHAPE_RECTANGULAR]->get_value("rect_size")); } catch (const std::exception & /* e */) { return; } try { rect_origin = boost::any_cast<Vec2d>(m_optgroups[SHAPE_RECTANGULAR]->get_value("rect_origin")); } catch (const std::exception & /* e */) { return; } auto x = rect_size(0); auto y = rect_size(1); // empty strings or '-' or other things if (x == 0 || y == 0) return; double x0 = 0.0; double y0 = 0.0; double x1 = x; double y1 = y; auto dx = rect_origin(0); auto dy = rect_origin(1); x0 -= dx; x1 -= dx; y0 -= dy; y1 -= dy; m_canvas->m_bed_shape = { Vec2d(x0, y0), Vec2d(x1, y0), Vec2d(x1, y1), Vec2d(x0, y1)}; } else if(page_idx == SHAPE_CIRCULAR) { double diameter; try{ diameter = boost::any_cast<double>(m_optgroups[SHAPE_CIRCULAR]->get_value("diameter")); } catch (const std::exception & /* e */) { return; } if (diameter == 0.0) return ; auto r = diameter / 2; auto twopi = 2 * PI; auto edges = 60; std::vector<Vec2d> points; for (size_t i = 1; i <= 60; ++i) { auto angle = i * twopi / edges; points.push_back(Vec2d(r*cos(angle), r*sin(angle))); } m_canvas->m_bed_shape = points; } // $self->{on_change}->(); update_preview(); }
void TestApp::test_vector2(void) { Console::write_line(" Header: cl_vector.h"); Console::write_line(" Class: Vec2"); Console::write_line(" Function: rotate()"); { Vec2i test_a; Vec2i hotspot(1,3); test_a = Vec2i(4,5); test_a.rotate(hotspot, Angle(0, angle_degrees)); if (test_a != Vec2i(4, 5)) fail(); test_a = Vec2i(4,5); test_a.rotate(hotspot, Angle(90, angle_degrees)); if (test_a != Vec2i(-1, 6)) fail(); test_a = Vec2i(4,5); test_a.rotate(hotspot, Angle(180, angle_degrees)); if (test_a != Vec2i(-2, 1)) fail(); test_a = Vec2i(4,5); test_a.rotate(hotspot, Angle(270, angle_degrees)); if (test_a != Vec2i(3, 0)) fail(); test_a = Vec2i(4,5); test_a.rotate(hotspot, Angle(360, angle_degrees)); if (test_a != Vec2i(4, 5)) fail(); test_a = Vec2i(4,5); test_a.rotate(Vec2i(0,0), Angle(180, angle_degrees)); if (test_a != Vec2i(-4, -5)) fail(); } Console::write_line(" Function: distance()"); { Vec2d test_a(2.0,3.0); Vec2d test_b(3.0,4.0); if (test_a.distance(test_b) != sqrt(1.0 + 1.0 )) fail(); } Console::write_line(" Function: normalize()"); { Vec2d testi(3.0,4.0); testi.normalize(); if (testi != Vec2d(3.0/sqrt(25.0), 4.0/sqrt(25.0))) fail(); } Console::write_line(" Function: static normalize()"); { Vec2d testi(3.0,4.0); if (Vec2d::normalize(testi) != Vec2d(3.0/sqrt(25.0), 4.0/sqrt(25.0))) fail(); } Console::write_line(" Function: length()"); { Vec2d testi(3.0,4.0); if (testi.length() != sqrt(25.0 )) fail(); } Console::write_line(" Function: dot()"); { Vec2d test_a(3.0,4.0); Vec2d test_b(13.0,14.0); if (test_a.dot(test_b) != ((3.0 * 13.0)+ (4.0*14.0))) fail(); } Console::write_line(" Function: operator += (const Vec2<Type>& vector)"); { Vec2d testd(2.5, 3.5); testd += Vec2d(1.0, 2.0); if (testd.x != 3.5) fail(); if (testd.y != 5.5) fail(); Vec2i testi(2, 3); testi += Vec2i(1, 2); if (testi.x != 3) fail(); if (testi.y != 5) fail(); } Console::write_line(" Function: operator += ( Type value)"); { Vec2d testd(2.5, 3.5); double valued = 2.0; testd += valued; if (testd.x != 4.5) fail(); if (testd.y != 5.5) fail(); Vec2i testi(2, 3); int valuei = 2; testi += valuei; if (testi.x != 4) fail(); if (testi.y != 5) fail(); } Console::write_line(" Function: operator + (Type value)"); { Vec2d testd(2.5, 3.5); double valued = 2.0; testd = testd + valued; if (testd.x != 4.5) fail(); if (testd.y != 5.5) fail(); Vec2i testi(2, 3); int valuei = 2; testi = testi + valuei; if (testi.x != 4) fail(); if (testi.y != 5) fail(); } Console::write_line(" Function: operator + (const Vec2<Type>& vector)"); { Vec2d testd(2.5, 3.5); testd = testd + Vec2d(1.5, 2.5); if (testd.x != 4.0) fail(); if (testd.y != 6.0) fail(); Vec2i testi(2, 3); testi = testi + Vec2i(1, 2); if (testi.x != 3) fail(); if (testi.y != 5) fail(); } Console::write_line(" Function: operator -= (const Vec2<Type>& vector)"); { Vec2d testd(2.5, 3.5); testd -= Vec2d(1.0, 2.0); if (testd.x != 1.5) fail(); if (testd.y != 1.5) fail(); Vec2i testi(2, 3); testi -= Vec2i(1, 2); if (testi.x != 1) fail(); if (testi.y != 1) fail(); } Console::write_line(" Function: operator -= ( Type value)"); { Vec2d testd(2.5, 3.5); double valued = 2.0; testd -= valued; if (testd.x != 0.5) fail(); if (testd.y != 1.5) fail(); Vec2i testi(2, 3); int valuei = 2; testi -= valuei; if (testi.x != 0) fail(); if (testi.y != 1) fail(); } Console::write_line(" Function: operator - (Type value)"); { Vec2d testd(2.5, 3.5); double valued = 2.0; testd = testd - valued; if (testd.x != 0.5) fail(); if (testd.y != 1.5) fail(); Vec2i testi(2, 3); int valuei = 2; testi = testi - valuei; if (testi.x != 0) fail(); if (testi.y != 1) fail(); } Console::write_line(" Function: operator - (const Vec2<Type>& vector)"); { Vec2d testd(2.5, 3.5); testd = testd - Vec2d(1.5, 2.5); if (testd.x != 1.0) fail(); if (testd.y != 1.0) fail(); Vec2i testi(2, 3); testi = testi - Vec2i(1, 2); if (testi.x != 1) fail(); if (testi.y != 1) fail(); } Console::write_line(" Function: operator *= (const Vec2<Type>& vector)"); { Vec2d testd(2.5, 3.5); testd *= Vec2d(1.0, 2.0); if (testd.x != 2.5) fail(); if (testd.y != 7.0) fail(); Vec2i testi(2, 3); testi *= Vec2i(1, 2); if (testi.x != 2) fail(); if (testi.y != 6) fail(); } Console::write_line(" Function: operator *= ( Type value)"); { Vec2d testd(2.5, 3.5); double valued = 2.0; testd *= valued; if (testd.x != 5.0) fail(); if (testd.y != 7.0) fail(); Vec2i testi(2, 3); int valuei = 2; testi *= valuei; if (testi.x != 4) fail(); if (testi.y != 6) fail(); } Console::write_line(" Function: operator * (Type value)"); { Vec2d testd(2.5, 3.5); double valued = 2.0; testd = testd * valued; if (testd.x != 5.0) fail(); if (testd.y != 7.0) fail(); Vec2i testi(2, 3); int valuei = 2; testi = testi * valuei; if (testi.x != 4) fail(); if (testi.y != 6) fail(); } Console::write_line(" Function: operator * (const Vec2<Type>& vector)"); { Vec2d testd(2.5, 3.5); testd = testd * Vec2d(1.5, 2.5); if (testd.x != 3.75) fail(); if (testd.y != 8.75) fail(); Vec2i testi(2, 3); testi = testi * Vec2i(1, 2); if (testi.x != 2) fail(); if (testi.y != 6) fail(); } Console::write_line(" Function: operator /= (const Vec2<Type>& vector)"); { Vec2d testd(2.5, 3.5); testd /= Vec2d(1.0, 2.0); if (testd.x != 2.5) fail(); if (testd.y != 1.75) fail(); Vec2i testi(2, 10); testi /= Vec2i(1, 2); if (testi.x != 2) fail(); if (testi.y != 5) fail(); } Console::write_line(" Function: operator /= ( Type value)"); { Vec2d testd(2.5, 3.5); double valued = 2.0; testd /= valued; if (testd.x != 1.25) fail(); if (testd.y != 1.75) fail(); Vec2i testi(2, 10); int valuei = 2; testi /= valuei; if (testi.x != 1) fail(); if (testi.y != 5) fail(); } Console::write_line(" Function: operator / (Type value)"); { Vec2d testd(2.5, 3.5); double valued = 2.0; testd = testd / valued; if (testd.x != 1.25) fail(); if (testd.y != 1.75) fail(); Vec2i testi(2, 10); int valuei = 2; testi = testi / valuei; if (testi.x != 1) fail(); if (testi.y != 5) fail(); } Console::write_line(" Function: operator / (const Vec2<Type>& vector)"); { Vec2d testd(2.5, 3.5); testd = testd / Vec2d(1.0, 2.5); if (testd.x != 2.5) fail(); if (testd.y != 1.4) fail(); Vec2i testi(2, 10); testi = testi / Vec2i(1, 2); if (testi.x != 2) fail(); if (testi.y != 5) fail(); } Console::write_line(" Function: operator = (const Vec2<Type>& vector)"); { Vec2d testd(2.5, 3.5); testd = Vec2d(1.0, 2.0); if (testd.x != 1.0) fail(); if (testd.y != 2.0) fail(); Vec2i testi(2, 3); testi = Vec2i(1, 2); if (testi.x != 1) fail(); if (testi.y != 2) fail(); } Console::write_line(" Function: operator == (const Vec2<Type>& vector)"); { Vec2d testd(2.5, 3.5); if (testd == Vec2d(1.0, 2.0)) fail(); if (testd == Vec2d(2.5, 2.0)) fail(); if (!(testd == Vec2d(2.5, 3.5))) fail(); Vec2i testi(2, 3); if (testi == Vec2i(1, 2)) fail(); if (testi == Vec2i(2, 2)) fail(); if (!(testi == Vec2i(2, 3))) fail(); } Console::write_line(" Function: operator != (const Vec2<Type>& vector)"); { Vec2d testd(2.5, 3.5); if (!(testd != Vec2d(1.0, 2.0))) fail(); if (!(testd != Vec2d(2.5, 2.0))) fail(); if ((testd != Vec2d(2.5, 3.5))) fail(); Vec2i testi(2, 3); if (!(testi != Vec2i(1, 2))) fail(); if (!(testi != Vec2i(2, 2))) fail(); if ((testi != Vec2i(2, 3))) fail(); } Console::write_line(" Function: round()"); { Vec2d testd(2.0, 2.5); testd.round(); if (testd.x != 2.0) fail(); if (testd.y != 3.0) fail(); Vec2f testf(2.0f, 2.5f); testf.round(); if (testf.x != 2.0f) fail(); if (testf.y != 3.0f) fail(); } Console::write_line(" Function: static round()"); { Vec2d testd(2.0, 2.5); Vec2d destd = Vec2d::round(testd); if (destd.x != 2.0) fail(); if (destd.y != 3.0) fail(); Vec2f testf(2.0f, 2.5f); Vec2f destf = Vec2f::round(testf); if (destf.x != 2.0f) fail(); if (destf.y != 3.0f) fail(); } }
void BedShapePanel::build_panel(ConfigOptionPoints* default_pt) { // on_change(nullptr); auto box = new wxStaticBox(this, wxID_ANY, _(L("Shape"))); auto sbsizer = new wxStaticBoxSizer(box, wxVERTICAL); // shape options m_shape_options_book = new wxChoicebook(this, wxID_ANY, wxDefaultPosition, wxSize(25*wxGetApp().em_unit(), -1), wxCHB_TOP); sbsizer->Add(m_shape_options_book); auto optgroup = init_shape_options_page(_(L("Rectangular"))); ConfigOptionDef def; def.type = coPoints; def.default_value = new ConfigOptionPoints{ Vec2d(200, 200) }; def.label = L("Size"); def.tooltip = L("Size in X and Y of the rectangular plate."); Option option(def, "rect_size"); optgroup->append_single_option_line(option); def.type = coPoints; def.default_value = new ConfigOptionPoints{ Vec2d(0, 0) }; def.label = L("Origin"); def.tooltip = L("Distance of the 0,0 G-code coordinate from the front left corner of the rectangle."); option = Option(def, "rect_origin"); optgroup->append_single_option_line(option); optgroup = init_shape_options_page(_(L("Circular"))); def.type = coFloat; def.default_value = new ConfigOptionFloat(200); def.sidetext = L("mm"); def.label = L("Diameter"); def.tooltip = L("Diameter of the print bed. It is assumed that origin (0,0) is located in the center."); option = Option(def, "diameter"); optgroup->append_single_option_line(option); optgroup = init_shape_options_page(_(L("Custom"))); Line line{ "", "" }; line.full_width = 1; line.widget = [this](wxWindow* parent) { auto btn = new wxButton(parent, wxID_ANY, _(L("Load shape from STL...")), wxDefaultPosition, wxDefaultSize); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { load_stl(); })); return sizer; }; optgroup->append_line(line); Bind(wxEVT_CHOICEBOOK_PAGE_CHANGED, ([this](wxCommandEvent e) { update_shape(); })); // right pane with preview canvas m_canvas = new Bed_2D(this); m_canvas->m_bed_shape = default_pt->values; // main sizer auto top_sizer = new wxBoxSizer(wxHORIZONTAL); top_sizer->Add(sbsizer, 0, wxEXPAND | wxLeft | wxTOP | wxBOTTOM, 10); if (m_canvas) top_sizer->Add(m_canvas, 1, wxEXPAND | wxALL, 10) ; SetSizerAndFit(top_sizer); set_shape(default_pt); update_preview(); }
Vec3d CubeMap::getColor(ray r) const { int axis, front, left, right, top, bottom; double u,v; Vec3d dir = r.getDirection(); if (fabs(dir[0]) > fabs(dir[1])) if (fabs(dir[0]) > fabs(dir[2])) { axis = 0; bottom = 3; top = 2; if (dir[0] > 0.0) { front = 0; left = 4; right = 5; } else { front = 1; left = 5; right = 4; } } else { axis = 2; bottom = 3; top = 2; if (dir[2] > 0.0) { front = 5; left = 0; right = 1; } else { front = 4; left = 1; right = 0; } } else if (fabs(dir[1]) > fabs(dir[2])) { axis = 1; left = 1; right = 0; if (dir[1] > 0.0) { front = 2; bottom = 4; top = 5; } else { front = 3; bottom = 5; top = 4; } } else { axis = 2; bottom = 3; top = 2; if (dir[2] > 0.0) { front = 5; left = 0; right = 1; } else { front = 4; left = 1; right = 0; } } if (axis == 0) { u = dir[2]/dir[0]; if (dir[0] > 0.0) v = dir[1]/dir[0]; else v = -dir[1]/dir[0]; } else if (axis == 1) { if (dir[1] > 0.0) u = dir[0]/dir[1]; else u = -dir[0]/dir[1]; v = dir[2]/dir[1]; } else if (axis == 2) { u = -dir[0]/dir[2]; if (dir[2] > 0.0) v = dir[1]/dir[2]; else v = -dir[1]/dir[2]; } u = (u + 1.0)/2.0; v = (v + 1.0)/2.0; int filterwidth = traceUI->getFilterWidth(); if (r.type() != ray::VISIBILITY || filterwidth == 1) return tMap[front]->getMappedValue(Vec2d(u, v)); int fw = (filterwidth + 1)/2 - 1; int rm = filterwidth - fw; int width = tMap[front]->getWidth(); int height = tMap[front]->getHeight(); double delu = 1.0/width; double delv = 1.0/height; int x = floor(0.5 + u * (width - 1)); int y = floor(0.5 + v * (height - 1)); double startu = delu * (x - fw); double startv = delv * (y - fw); double nextu = startu; double nextv = startv; double xslope = 1.0/(((double)filterwidth + 1) / 2.0 * delu); double yslope = 1.0/(((double)filterwidth + 1) / 2.0 * delv); double correct = 0.0; Vec3d thePixel = Vec3d(0.0, 0.0, 0.0); for (int jj = -fw; jj < rm; jj++) { for (int ii = -fw; ii < rm; ii++) { int xindex = x + ii; int yindex = y + jj; if (xindex < 0 && yindex < 0) continue; if (xindex >= width && yindex >= height) continue; if (xindex >= width && yindex < 0) continue; if (xindex < 0 && yindex >= height) continue; int theMap = front; if (yindex < 0) { theMap = bottom; if (axis == 0) if (dir[0] > 0) { yindex = height - 1 - xindex; xindex = width + jj; } else { yindex = xindex; xindex = -1 - jj; } else if (axis == 1) if (dir[1] > 0) yindex = height + jj; else { yindex = -1 - jj; xindex = width - 1 - xindex; } else if (axis == 2) if (dir[2] > 0) { yindex = -1 - jj; xindex = width - 1 - xindex; } else yindex = height + jj; } else if (yindex >= height) { theMap = top; if (axis == 0) if (dir[0] > 0) { yindex = xindex; xindex = width - jj; } else { yindex = height - 1 - xindex; xindex = jj - 1; } else if (axis == 1) if (dir[1] > 0) { yindex = height - jj; xindex = width - 1 - xindex; } else yindex = jj - 1; else if (axis == 2) if (dir[2] > 0) { yindex = height - jj; xindex = width - 1 - xindex; } else yindex = jj - 1; } else if (xindex < 0) { theMap = left; if (axis == 0 || axis == 2) xindex = width + ii; else if (axis == 1) if (dir[1] > 0) { xindex = width - 1 - yindex; yindex = height + ii; } else { xindex = yindex; yindex = -1 - ii; } } else if (xindex >= width) { theMap = right; if (axis == 0 || axis == 2) xindex = ii - 1; else if (axis == 1) if (dir[1] > 0) { xindex = yindex; yindex = height - ii; } else { xindex = width - 1 - yindex; yindex = ii - 1; } } double du = u - nextu; double dv = v - nextv; double weight = (1.0 - fabs(du * xslope)) * (1.0 - fabs(dv * yslope)); nextu += delu; correct += weight; thePixel += tMap[theMap]->getPixelAt(xindex, yindex) * weight; } nextu = startu; nextv += delv; } thePixel /= correct; return thePixel; }
Pointfs FillOctagramSpiral::_generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y) { // Radius to achieve. coordf_t rmax = std::sqrt(coordf_t(max_x)*coordf_t(max_x)+coordf_t(max_y)*coordf_t(max_y)) * std::sqrt(2.) + 1.5; // Now unwind the spiral. coordf_t r = 0; coordf_t r_inc = sqrt(2.); Pointfs out; out.push_back(Vec2d(0, 0)); while (r < rmax) { r += r_inc; coordf_t rx = r / sqrt(2.); coordf_t r2 = r + rx; out.push_back(Vec2d( r, 0.)); out.push_back(Vec2d( r2, rx)); out.push_back(Vec2d( rx, rx)); out.push_back(Vec2d( rx, r2)); out.push_back(Vec2d(0., r)); out.push_back(Vec2d(-rx, r2)); out.push_back(Vec2d(-rx, rx)); out.push_back(Vec2d(-r2, rx)); out.push_back(Vec2d(-r, 0.)); out.push_back(Vec2d(-r2, -rx)); out.push_back(Vec2d(-rx, -rx)); out.push_back(Vec2d(-rx, -r2)); out.push_back(Vec2d(0., -r)); out.push_back(Vec2d( rx, -r2)); out.push_back(Vec2d( rx, -rx)); out.push_back(Vec2d( r2+r_inc, -rx)); } return out; }
Vec2d Delta () const { return Vec2d (p2->X()-p1->X(), p2->Y()-p1->Y()); }
void triangulatePoints(InputArrayOfArrays _points2d, InputArrayOfArrays _projection_matrices, OutputArray _points3d) { // check size_t nviews = (unsigned) _points2d.total(); CV_Assert(nviews >= 2 && nviews == _projection_matrices.total()); // inputs size_t n_points; vector<Mat_<double> > points2d(nviews); vector<Matx34d> projection_matrices(nviews); { vector<Mat> points2d_tmp; _points2d.getMatVector(points2d_tmp); n_points = points2d_tmp[0].cols; vector<Mat> projection_matrices_tmp; _projection_matrices.getMatVector(projection_matrices_tmp); // Make sure the dimensions are right for(size_t i=0; i<nviews; ++i) { CV_Assert(points2d_tmp[i].rows == 2 && points2d_tmp[i].cols == n_points); if (points2d_tmp[i].type() == CV_64F) points2d[i] = points2d_tmp[i]; else points2d_tmp[i].convertTo(points2d[i], CV_64F); CV_Assert(projection_matrices_tmp[i].rows == 3 && projection_matrices_tmp[i].cols == 4); if (projection_matrices_tmp[i].type() == CV_64F) projection_matrices[i] = projection_matrices_tmp[i]; else projection_matrices_tmp[i].convertTo(projection_matrices[i], CV_64F); } } // output _points3d.create(3, n_points, CV_64F); cv::Mat points3d = _points3d.getMat(); // Two view if( nviews == 2 ) { const Mat_<double> &xl = points2d[0], &xr = points2d[1]; const Matx34d & Pl = projection_matrices[0]; // left matrix projection const Matx34d & Pr = projection_matrices[1]; // right matrix projection // triangulate for( unsigned i = 0; i < n_points; ++i ) { Vec3d point3d; triangulateDLT( Vec2d(xl(0,i), xl(1,i)), Vec2d(xr(0,i), xr(1,i)), Pl, Pr, point3d ); for(char j=0; j<3; ++j) points3d.at<double>(j, i) = point3d[j]; } } else if( nviews > 2 ) { // triangulate for( unsigned i=0; i < n_points; ++i ) { // build x matrix (one point per view) Mat_<double> x( 2, nviews ); for( unsigned k=0; k < nviews; ++k ) { points2d.at(k).col(i).copyTo( x.col(k) ); } Vec3d point3d; nViewTriangulate( x, projection_matrices, point3d ); for(char j=0; j<3; ++j) points3d.at<double>(j, i) = point3d[j]; } } }
inline Vec2d operator+ (const Vec2d & v1, const Vec2d & v2) { return Vec2d (v1.X() + v2.X(), v1.Y() + v2.Y()); }
double TileNode::Transition::getCost(const Vec2d& selfSpeed, const TileNode& thisNode) { static const double TURN_PENALTY = Map::NORMAL_TURN_COST; static const double TURN_180_PENALTY = 4 * Map::NORMAL_TURN_COST; static const double WAYPOINT_OUT_OF_ORDER_PENALTY = Map::NORMAL_TURN_COST; // TODO - increase? // it's not so good to go through incorrect waypoint static const double ZIGZAZ_TURN_PRIZE = -Map::NORMAL_TURN_COST / 1.5; // zigzag turn is slightly better then usual turn double cost = Map::NORMAL_TURN_COST; AbsoluteDirection previousTurn = m_cachedParent == nullptr ? m_turnedDirection/*assume no change*/ : m_cachedParent->m_transition.m_turnedDirection; if (m_turnedDirection != previousTurn) cost += TURN_PENALTY; AbsoluteDirection minDirection = std::min(m_turnedDirection, previousTurn); AbsoluteDirection maxDirection = std::max(m_turnedDirection, previousTurn); if ((minDirection == AbsoluteDirection::LEFT && maxDirection == AbsoluteDirection::RIGHT) || (minDirection == AbsoluteDirection::UP && maxDirection == AbsoluteDirection::DOWN)) { cost += TURN_180_PENALTY; } TileNode* prePrevious = m_cachedParent != nullptr ? m_cachedParent->m_transition.m_cachedParent : nullptr; bool isZigzag = m_isZigzag // already calculated || ( prePrevious != nullptr && prePrevious->m_transition.m_turnedDirection == m_turnedDirection && m_cachedParent->m_transition.m_turnedDirection != m_turnedDirection ); if (isZigzag) { cost += ZIGZAZ_TURN_PRIZE; } m_isZigzag = isZigzag; if (m_cachedParent != nullptr) m_cachedParent->m_transition.m_isZigzag = isZigzag; if (thisNode.m_isWaypoint) cost += WAYPOINT_OUT_OF_ORDER_PENALTY; // speed vector may become a bonus or penalty for transitions near start bool isMoving = selfSpeed.m_x != 0 || selfSpeed.m_y != 0; if (m_cachedParent != nullptr && isMoving) { int tilesFromStart = 0; Vec2d correctedSpeed = selfSpeed; TileNode* previousNode = m_cachedParent->m_transition.m_cachedParent; while (previousNode != nullptr) { correctedSpeed /= 2; // further from start -> less penalty previousNode = previousNode->m_transition.m_cachedParent; if (++tilesFromStart > 2) { // too far, no sense to calculate correctedSpeed = Vec2d(0, 0); break; } } // remove "noise" if (std::abs(correctedSpeed.m_x) < 1) correctedSpeed.m_x = 0; if (std::abs(correctedSpeed.m_y) < 1) correctedSpeed.m_y = 0; // todo - use tilesFromStart? Vec2d turnVector = Vec2d::fromPoint(thisNode.m_pos - m_cachedParent->m_pos); double directionPrize = Vec2d::dot(correctedSpeed, turnVector) / selfSpeed.length(); // [-1; +1] // almost no penalty after log2(8) = 3 tiles static const double SPEED_VECTOR_PENALTY = -Map::NORMAL_TURN_COST * 16; // negative prize * negative penalty = positive cost incerment static const double SPEED_VECTOR_PRIZE = -Map::NORMAL_TURN_COST * 2; // positive prize * negative penalty = negative cost increment double costIncrement = directionPrize > 0 ? directionPrize * SPEED_VECTOR_PRIZE : directionPrize * SPEED_VECTOR_PENALTY; double newCost = cost + costIncrement; cost = std::max(newCost, Map::MIN_TURN_COST); } return cost; }