aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xjs/lib/geom/sub-path.js84
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
587GLSubpath.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
598GLSubpath.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
588GLSubpath.prototype.pickPath = function (pickX, pickY, pickZ, radius) { 672GLSubpath.prototype.pickPath = function (pickX, pickY, pickZ, radius) {
589 var numAnchors = this._Anchors.length; 673 var numAnchors = this._Anchors.length;