Flutter Engine
The Flutter Engine
Public Member Functions | Public Attributes | List of all members
ActiveEdge Struct Reference

Public Member Functions

 ActiveEdge ()
 
 ActiveEdge (const SkPoint &p0, const SkVector &v, uint16_t index0, uint16_t index1)
 
bool aboveIfLeft (const ActiveEdge *that) const
 
bool above (const ActiveEdge *that) const
 
bool intersect (const SkPoint &q0, const SkVector &w, uint16_t index0, uint16_t index1) const
 
bool intersect (const ActiveEdge *edge)
 
bool lessThan (const ActiveEdge *that) const
 
bool equals (uint16_t index0, uint16_t index1) const
 

Public Attributes

OffsetSegment fSegment
 
uint16_t fIndex0
 
uint16_t fIndex1
 
ActiveEdgefChild [2]
 
ActiveEdgefAbove
 
ActiveEdgefBelow
 
int32_t fRed
 

Detailed Description

Definition at line 554 of file SkPolyUtils.cpp.

Constructor & Destructor Documentation

◆ ActiveEdge() [1/2]

ActiveEdge::ActiveEdge ( )
inline

Definition at line 555 of file SkPolyUtils.cpp.

555: fChild{ nullptr, nullptr }, fAbove(nullptr), fBelow(nullptr), fRed(false) {}
ActiveEdge * fAbove
ActiveEdge * fBelow
ActiveEdge * fChild[2]
int32_t fRed

◆ ActiveEdge() [2/2]

ActiveEdge::ActiveEdge ( const SkPoint p0,
const SkVector v,
uint16_t  index0,
uint16_t  index1 
)
inline

Definition at line 556 of file SkPolyUtils.cpp.

557 : fSegment({ p0, v })
558 , fIndex0(index0)
559 , fIndex1(index1)
560 , fAbove(nullptr)
561 , fBelow(nullptr)
562 , fRed(true) {
563 fChild[0] = nullptr;
564 fChild[1] = nullptr;
565 }
uint16_t fIndex1
uint16_t fIndex0
OffsetSegment fSegment

Member Function Documentation

◆ above()

bool ActiveEdge::above ( const ActiveEdge that) const
inline

Definition at line 624 of file SkPolyUtils.cpp.

624 {
625 const SkPoint& p0 = this->fSegment.fP0;
626 const SkPoint& q0 = that->fSegment.fP0;
627 if (right(p0, q0)) {
628 return !that->aboveIfLeft(this);
629 } else {
630 return this->aboveIfLeft(that);
631 }
632 }
static bool right(const SkPoint &p0, const SkPoint &p1)
bool aboveIfLeft(const ActiveEdge *that) const

◆ aboveIfLeft()

bool ActiveEdge::aboveIfLeft ( const ActiveEdge that) const
inline

Definition at line 570 of file SkPolyUtils.cpp.

570 {
571 const SkPoint& p0 = this->fSegment.fP0;
572 const SkPoint& q0 = that->fSegment.fP0;
573 SkASSERT(p0.fX <= q0.fX);
574 SkVector d = q0 - p0;
575 const SkVector& v = this->fSegment.fV;
576 const SkVector& w = that->fSegment.fV;
577 // The idea here is that if the vector between the origins of the two segments (d)
578 // rotates counterclockwise up to the vector representing the "this" segment (v),
579 // then we know that "this" is above "that". If the result is clockwise we say it's below.
580 if (this->fIndex0 != that->fIndex0) {
581 SkScalar cross = d.cross(v);
582 if (cross > kCrossTolerance) {
583 return true;
584 } else if (cross < -kCrossTolerance) {
585 return false;
586 }
587 } else if (this->fIndex1 == that->fIndex1) {
588 return false;
589 }
590 // At this point either the two origins are nearly equal or the origin of "that"
591 // lies on dv. So then we try the same for the vector from the tail of "this"
592 // to the head of "that". Again, ccw means "this" is above "that".
593 // d = that.P1 - this.P0
594 // = that.fP0 + that.fV - this.fP0
595 // = that.fP0 - this.fP0 + that.fV
596 // = old_d + that.fV
597 d += w;
598 SkScalar cross = d.cross(v);
599 if (cross > kCrossTolerance) {
600 return true;
601 } else if (cross < -kCrossTolerance) {
602 return false;
603 }
604 // If the previous check fails, the two segments are nearly collinear
605 // First check y-coord of first endpoints
606 if (p0.fX < q0.fX) {
607 return (p0.fY >= q0.fY);
608 } else if (p0.fY > q0.fY) {
609 return true;
610 } else if (p0.fY < q0.fY) {
611 return false;
612 }
613 // The first endpoints are the same, so check the other endpoint
614 SkPoint p1 = p0 + v;
615 SkPoint q1 = q0 + w;
616 if (p1.fX < q1.fX) {
617 return (p1.fY >= q1.fY);
618 } else {
619 return (p1.fY > q1.fY);
620 }
621 }
#define SkASSERT(cond)
Definition: SkAssert.h:116
constexpr SkScalar kCrossTolerance
Definition: SkPolyUtils.cpp:41
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
float SkScalar
Definition: extension.cpp:12
int64_t cross(Point d0, Point d1)
Definition: Myers.cpp:55
SkScalar w
float fX
x-axis value
Definition: SkPoint_impl.h:164
float fY
y-axis value
Definition: SkPoint_impl.h:165

◆ equals()

bool ActiveEdge::equals ( uint16_t  index0,
uint16_t  index1 
) const
inline

Definition at line 684 of file SkPolyUtils.cpp.

684 {
685 return (this->fIndex0 == index0 && this->fIndex1 == index1);
686 }

◆ intersect() [1/2]

bool ActiveEdge::intersect ( const ActiveEdge edge)
inline

Definition at line 673 of file SkPolyUtils.cpp.

673 {
674 return this->intersect(edge->fSegment.fP0, edge->fSegment.fV, edge->fIndex0, edge->fIndex1);
675 }
bool intersect(const SkPoint &q0, const SkVector &w, uint16_t index0, uint16_t index1) const

◆ intersect() [2/2]

bool ActiveEdge::intersect ( const SkPoint q0,
const SkVector w,
uint16_t  index0,
uint16_t  index1 
) const
inline

Definition at line 634 of file SkPolyUtils.cpp.

634 {
635 // check first to see if these edges are neighbors in the polygon
636 if (this->fIndex0 == index0 || this->fIndex1 == index0 ||
637 this->fIndex0 == index1 || this->fIndex1 == index1) {
638 return false;
639 }
640
641 // We don't need the exact intersection point so we can do a simpler test here.
642 const SkPoint& p0 = this->fSegment.fP0;
643 const SkVector& v = this->fSegment.fV;
644 SkPoint p1 = p0 + v;
645 SkPoint q1 = q0 + w;
646
647 // We assume some x-overlap due to how the edgelist works
648 // This allows us to simplify our test
649 // We need some slop here because storing the vector and recomputing the second endpoint
650 // doesn't necessary give us the original result in floating point.
651 // TODO: Store vector as double? Store endpoint as well?
652 SkASSERT(q0.fX <= p1.fX + SK_ScalarNearlyZero);
653
654 // if each segment straddles the other (i.e., the endpoints have different sides)
655 // then they intersect
656 bool result;
657 if (p0.fX < q0.fX) {
658 if (q1.fX < p1.fX) {
659 result = (compute_side(p0, v, q0)*compute_side(p0, v, q1) < 0);
660 } else {
661 result = (compute_side(p0, v, q0)*compute_side(q0, w, p1) > 0);
662 }
663 } else {
664 if (p1.fX < q1.fX) {
665 result = (compute_side(q0, w, p0)*compute_side(q0, w, p1) < 0);
666 } else {
667 result = (compute_side(q0, w, p0)*compute_side(p0, v, q1) > 0);
668 }
669 }
670 return result;
671 }
static int compute_side(const SkPoint &p0, const SkVector &v, const SkPoint &p)
Definition: SkPolyUtils.cpp:46
#define SK_ScalarNearlyZero
Definition: SkScalar.h:99
GAsyncResult * result

◆ lessThan()

bool ActiveEdge::lessThan ( const ActiveEdge that) const
inline

Definition at line 677 of file SkPolyUtils.cpp.

677 {
678 SkASSERT(!this->above(this));
679 SkASSERT(!that->above(that));
680 SkASSERT(!(this->above(that) && that->above(this)));
681 return this->above(that);
682 }
bool above(const ActiveEdge *that) const

Member Data Documentation

◆ fAbove

ActiveEdge* ActiveEdge::fAbove

Definition at line 692 of file SkPolyUtils.cpp.

◆ fBelow

ActiveEdge* ActiveEdge::fBelow

Definition at line 693 of file SkPolyUtils.cpp.

◆ fChild

ActiveEdge* ActiveEdge::fChild[2]

Definition at line 691 of file SkPolyUtils.cpp.

◆ fIndex0

uint16_t ActiveEdge::fIndex0

Definition at line 689 of file SkPolyUtils.cpp.

◆ fIndex1

uint16_t ActiveEdge::fIndex1

Definition at line 690 of file SkPolyUtils.cpp.

◆ fRed

int32_t ActiveEdge::fRed

Definition at line 694 of file SkPolyUtils.cpp.

◆ fSegment

OffsetSegment ActiveEdge::fSegment

Definition at line 688 of file SkPolyUtils.cpp.


The documentation for this struct was generated from the following file: