diff options
-rwxr-xr-x | js/lib/geom/sub-path.js | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/js/lib/geom/sub-path.js b/js/lib/geom/sub-path.js index ab54d1e9..0a65511b 100755 --- a/js/lib/geom/sub-path.js +++ b/js/lib/geom/sub-path.js | |||
@@ -584,6 +584,90 @@ GLSubpath.prototype.pickAnchor = function (pickX, pickY, pickZ, radius) { | |||
584 | return selAnchorIndex; | 584 | return selAnchorIndex; |
585 | }; | 585 | }; |
586 | 586 | ||
587 | GLSubpath.prototype.isWithinBBox =function(x,y,z){ | ||
588 | if (this._BBoxMin[0]>x || this._BBoxMin[1]>y || this._BBoxMin[2]>z){ | ||
589 | return false; | ||
590 | } | ||
591 | if (this._BBoxMax[0]<x || this._BBoxMax[1]<y || this._BBoxMax[2]<z){ | ||
592 | return false; | ||
593 | } | ||
594 | return true; | ||
595 | } | ||
596 | |||
597 | //pick the path point closest to the specified location, return null if some anchor point (or its handles) is within radius, else return the parameter distance | ||
598 | GLSubpath.prototype.pathHitTest = function (pickX, pickY, pickZ, radius) { | ||
599 | var numAnchors = this._Anchors.length; | ||
600 | var selAnchorIndex = -1; | ||
601 | var retParam = null; | ||
602 | var radSq = radius * radius; | ||
603 | var minDistance = Infinity; | ||
604 | |||
605 | //check if the location is close to the currently selected anchor position | ||
606 | if (this._selectedAnchorIndex>=0 && this._selectedAnchorIndex<this._Anchors.length){ | ||
607 | var distSq = this._Anchors[this._selectedAnchorIndex].getDistanceSq(pickX, pickY, pickZ); | ||
608 | //check the anchor point | ||
609 | if (distSq < minDistance && distSq < radSq) { | ||
610 | selAnchorIndex = this._selectedAnchorIndex; | ||
611 | minDistance = distSq; | ||
612 | } | ||
613 | } | ||
614 | //check the prev and next of the selected anchor if the above did not register a hit | ||
615 | if (this._selectedAnchorIndex>=0 && selAnchorIndex === -1) { | ||
616 | var distSq = this._Anchors[this._selectedAnchorIndex].getPrevDistanceSq(pickX, pickY, pickZ); | ||
617 | if (distSq < minDistance && distSq < radSq){ | ||
618 | selAnchorIndex = this._selectedAnchorIndex; | ||
619 | minDistance = distSq; | ||
620 | } else { | ||
621 | //check the next for this anchor point | ||
622 | distSq = this._Anchors[this._selectedAnchorIndex].getNextDistanceSq(pickX, pickY, pickZ); | ||
623 | if (distSq<minDistance && distSq<radSq){ | ||
624 | selAnchorIndex = this._selectedAnchorIndex; | ||
625 | minDistance = distSq; | ||
626 | } | ||
627 | } | ||
628 | } | ||
629 | |||
630 | //now check if the location is close to any anchor position | ||
631 | if (selAnchorIndex===-1) { | ||
632 | for (var i = 0; i < numAnchors; i++) { | ||
633 | var distSq = this._Anchors[i].getDistanceSq(pickX, pickY, pickZ); | ||
634 | //check the anchor point | ||
635 | if (distSq < minDistance && distSq < radSq) { | ||
636 | selAnchorIndex = i; | ||
637 | minDistance = distSq; | ||
638 | } | ||
639 | }//for every anchor i | ||
640 | } | ||
641 | |||
642 | //finally check if the location is close to the curve itself | ||
643 | if (selAnchorIndex===-1) { | ||
644 | //first check if the input location is within the bounding box | ||
645 | if (this.isWithinBBox(pickX,pickY,pickZ)){ | ||
646 | var numSegments = this._isClosed ? numAnchors : numAnchors-1; | ||
647 | for (var i = 0; i < numSegments; i++) { | ||
648 | var nextIndex = (i+1)%numAnchors; | ||
649 | //check if the point is close to the bezier segment between anchor i and anchor nextIndex | ||
650 | var controlPoints = [[this._Anchors[i].getPosX(),this._Anchors[i].getPosY(),this._Anchors[i].getPosZ()], | ||
651 | [this._Anchors[i].getNextX(),this._Anchors[i].getNextY(),this._Anchors[i].getNextZ()], | ||
652 | [this._Anchors[nextIndex].getPrevX(),this._Anchors[nextIndex].getPrevY(),this._Anchors[nextIndex].getPrevZ()], | ||
653 | [this._Anchors[nextIndex].getPosX(),this._Anchors[nextIndex].getPosY(),this._Anchors[nextIndex].getPosZ()]]; | ||
654 | var point = [pickX, pickY, pickZ]; | ||
655 | if (this._isWithinBoundingBox(point, controlPoints, radius)) { | ||
656 | //var intersectParam = this._checkIntersection(controlPoints, 0.0, 1.0, point, radius); | ||
657 | var intersectParam = this._checkIntersectionWithSamples(this._anchorSampleIndex[i], this._anchorSampleIndex[nextIndex], point, radius); | ||
658 | console.log("intersectParam:"+intersectParam); | ||
659 | if (intersectParam){ | ||
660 | selAnchorIndex=i; | ||
661 | retParam = intersectParam-i; //make the retParam go from 0 to 1 | ||
662 | break; | ||
663 | } | ||
664 | } | ||
665 | }//for every anchor i | ||
666 | }//if is within bbox | ||
667 | } | ||
668 | return [selAnchorIndex,retParam]; | ||
669 | } //GLSubpath.pathHitTest function | ||
670 | |||
587 | //pick the path point closest to the specified location, return null if some anchor point (or its handles) is within radius, else return the parameter distance | 671 | //pick the path point closest to the specified location, return null if some anchor point (or its handles) is within radius, else return the parameter distance |
588 | GLSubpath.prototype.pickPath = function (pickX, pickY, pickZ, radius) { | 672 | GLSubpath.prototype.pickPath = function (pickX, pickY, pickZ, radius) { |
589 | var numAnchors = this._Anchors.length; | 673 | var numAnchors = this._Anchors.length; |