123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- #include "edge-selectors.h"
- namespace msdfgen {
- TrueDistanceSelector::TrueDistanceSelector(const Point2 &p) : p(p) { }
- void TrueDistanceSelector::addEdge(const EdgeSegment *prevEdge, const EdgeSegment *edge, const EdgeSegment *nextEdge) {
- double dummy;
- SignedDistance distance = edge->signedDistance(p, dummy);
- if (distance < minDistance)
- minDistance = distance;
- }
- void TrueDistanceSelector::merge(const TrueDistanceSelector &other) {
- if (other.minDistance < minDistance)
- minDistance = other.minDistance;
- }
- TrueDistanceSelector::DistanceType TrueDistanceSelector::distance() const {
- return minDistance.distance;
- }
- bool PseudoDistanceSelectorBase::pointFacingEdge(const EdgeSegment *prevEdge, const EdgeSegment *edge, const EdgeSegment *nextEdge, const Point2 &p, double param) {
- if (param < 0) {
- Vector2 prevEdgeDir = -prevEdge->direction(1).normalize(true);
- Vector2 edgeDir = edge->direction(0).normalize(true);
- Vector2 pointDir = p-edge->point(0);
- return dotProduct(pointDir, edgeDir) >= dotProduct(pointDir, prevEdgeDir);
- }
- if (param > 1) {
- Vector2 edgeDir = -edge->direction(1).normalize(true);
- Vector2 nextEdgeDir = nextEdge->direction(0).normalize(true);
- Vector2 pointDir = p-edge->point(1);
- return dotProduct(pointDir, edgeDir) >= dotProduct(pointDir, nextEdgeDir);
- }
- return true;
- }
- PseudoDistanceSelectorBase::PseudoDistanceSelectorBase() : nearEdge(NULL), nearEdgeParam(0) { }
- void PseudoDistanceSelectorBase::addEdgeTrueDistance(const EdgeSegment *edge, const SignedDistance &distance, double param) {
- if (distance < minTrueDistance) {
- minTrueDistance = distance;
- nearEdge = edge;
- nearEdgeParam = param;
- }
- }
- void PseudoDistanceSelectorBase::addEdgePseudoDistance(const SignedDistance &distance) {
- SignedDistance &minPseudoDistance = distance.distance < 0 ? minNegativePseudoDistance : minPositivePseudoDistance;
- if (distance < minPseudoDistance)
- minPseudoDistance = distance;
- }
- void PseudoDistanceSelectorBase::merge(const PseudoDistanceSelectorBase &other) {
- if (other.minTrueDistance < minTrueDistance) {
- minTrueDistance = other.minTrueDistance;
- nearEdge = other.nearEdge;
- nearEdgeParam = other.nearEdgeParam;
- }
- if (other.minNegativePseudoDistance < minNegativePseudoDistance)
- minNegativePseudoDistance = other.minNegativePseudoDistance;
- if (other.minPositivePseudoDistance < minPositivePseudoDistance)
- minPositivePseudoDistance = other.minPositivePseudoDistance;
- }
- double PseudoDistanceSelectorBase::computeDistance(const Point2 &p) const {
- double minDistance = minTrueDistance.distance < 0 ? minNegativePseudoDistance.distance : minPositivePseudoDistance.distance;
- if (nearEdge) {
- SignedDistance distance = minTrueDistance;
- nearEdge->distanceToPseudoDistance(distance, p, nearEdgeParam);
- if (fabs(distance.distance) < fabs(minDistance))
- minDistance = distance.distance;
- }
- return minDistance;
- }
- SignedDistance PseudoDistanceSelectorBase::trueDistance() const {
- return minTrueDistance;
- }
- PseudoDistanceSelector::PseudoDistanceSelector(const Point2 &p) : p(p) { }
- void PseudoDistanceSelector::addEdge(const EdgeSegment *prevEdge, const EdgeSegment *edge, const EdgeSegment *nextEdge) {
- double param;
- SignedDistance distance = edge->signedDistance(p, param);
- addEdgeTrueDistance(edge, distance, param);
- if (pointFacingEdge(prevEdge, edge, nextEdge, p, param)) {
- edge->distanceToPseudoDistance(distance, p, param);
- addEdgePseudoDistance(distance);
- }
- }
- PseudoDistanceSelector::DistanceType PseudoDistanceSelector::distance() const {
- return computeDistance(p);
- }
- MultiDistanceSelector::MultiDistanceSelector(const Point2 &p) : p(p) { }
- void MultiDistanceSelector::addEdge(const EdgeSegment *prevEdge, const EdgeSegment *edge, const EdgeSegment *nextEdge) {
- double param;
- SignedDistance distance = edge->signedDistance(p, param);
- if (edge->color&RED)
- r.addEdgeTrueDistance(edge, distance, param);
- if (edge->color&GREEN)
- g.addEdgeTrueDistance(edge, distance, param);
- if (edge->color&BLUE)
- b.addEdgeTrueDistance(edge, distance, param);
- if (PseudoDistanceSelectorBase::pointFacingEdge(prevEdge, edge, nextEdge, p, param)) {
- edge->distanceToPseudoDistance(distance, p, param);
- if (edge->color&RED)
- r.addEdgePseudoDistance(distance);
- if (edge->color&GREEN)
- g.addEdgePseudoDistance(distance);
- if (edge->color&BLUE)
- b.addEdgePseudoDistance(distance);
- }
- }
- void MultiDistanceSelector::merge(const MultiDistanceSelector &other) {
- r.merge(other.r);
- g.merge(other.g);
- b.merge(other.b);
- }
- MultiDistanceSelector::DistanceType MultiDistanceSelector::distance() const {
- MultiDistance multiDistance;
- multiDistance.r = r.computeDistance(p);
- multiDistance.g = g.computeDistance(p);
- multiDistance.b = b.computeDistance(p);
- return multiDistance;
- }
- SignedDistance MultiDistanceSelector::trueDistance() const {
- SignedDistance distance = r.trueDistance();
- if (g.trueDistance() < distance)
- distance = g.trueDistance();
- if (b.trueDistance() < distance)
- distance = b.trueDistance();
- return distance;
- }
- MultiAndTrueDistanceSelector::MultiAndTrueDistanceSelector(const Point2 &p) : MultiDistanceSelector(p) { }
- MultiAndTrueDistanceSelector::DistanceType MultiAndTrueDistanceSelector::distance() const {
- MultiDistance multiDistance = MultiDistanceSelector::distance();
- MultiAndTrueDistance mtd;
- mtd.r = multiDistance.r;
- mtd.g = multiDistance.g;
- mtd.b = multiDistance.b;
- mtd.a = trueDistance().distance;
- return mtd;
- }
- }
|