def filter(self, coordinate):
     global _xDisp, _yDisp
     displacement = Coordinate(_xDisp, _yDisp)
     coordinate.setCoordinate(CoordUtil.add(coordinate, displacement))
Beispiel #2
0
 def filter(self, coordinate):
     global _xDisp, _yDisp
     displacement = Coordinate(_xDisp, _yDisp)
     coordinate.setCoordinate(CoordUtil.add(coordinate, displacement))
def _roadDraw(p, final=0):
    global _edit1, _laneWidths, _doBackup, _skip, _radius, _roadCenterLine
    roadEdgeLeft = ArrayList()
    roadEdgeRight = ArrayList()
    _roadCenterLine = ArrayList()
    try:
        laneWidth = float(_edit1.text)
    except:
        laneWidth = p[0].distance(p[1])
    roadWidth = laneWidth * 2.0
    if p.size() == 3:
        _laneWidths = [laneWidth, laneWidth]
    _edit1.text = "%f" % laneWidth
    p.remove(0)
    if len(_laneWidths) < p.size():
        _laneWidths.append(laneWidth)
    else:
        _laneWidths[-1] = laneWidth
    #handle the backup button
    for skip in _skip:
        p.remove(skip)
    skip = 0
    if _doBackup:
        skip = p.size() - 2  #index of prior point
        _skip.append(skip)  #we'll need it next time we get p[]
        _doBackup = 0
        if skip > 1:  #lane width skips can be handled now
            _laneWidths = _laneWidths[:skip] + _laneWidths[skip + 1:]
    if skip > 1:
        p.remove(skip)
    left = 1
    right = 0
    #crank in the initial road rectangle left and right edges
    roadEdgeLeft.add(
        GeoUtils.perpendicularVector(p[0], p[1], _laneWidths[0], left))
    roadEdgeRight.add(
        GeoUtils.perpendicularVector(p[0], p[1], _laneWidths[0], left))
    roadEdgeRight.add(
        GeoUtils.perpendicularVector(p[0], p[1], _laneWidths[0], right))
    roadEdgeLeft.add(
        GeoUtils.perpendicularVector(p[1], p[0], _laneWidths[1], right))
    roadEdgeRight.add(
        GeoUtils.perpendicularVector(p[1], p[0], _laneWidths[1], left))
    _roadCenterLine.add(p[0])
    _roadCenterLine.add(p[1])
    #calculate the left and right edges of the rest of the road
    currPos = 1
    endPos = p.size(
    ) - 1  #the last point in the array is the curr mouse pos adjusted by constraints
    perp1 = GeoUtils.perpendicularVector(p[1], p[0], roadWidth, right)
    while currPos < endPos:
        midPt = CU.add(p[currPos],
                       CU.divide(CU.subtract(p[currPos + 1], p[currPos]), 2))
        perp2 = GeoUtils.perpendicularVector(midPt, p[currPos], roadWidth,
                                             right)
        center = GeoUtils.getIntersection(p[currPos], perp1, midPt, perp2)
        if center.z == 0.0:  #check for parallel vectors
            radius = center.distance(p[currPos])
            d = p[currPos].distance(midPt)
            curved = radius / d < 50  #compare to tangent threshold
        else:
            curved = 0
        if curved:  #construct a circular curve
            circularArc = (_laneWidths[currPos] == _laneWidths[currPos + 1])
            radius = center.distance(p[currPos])
            toLeft = computeOrientation(p[currPos], perp1,
                                        p[currPos + 1]) == LEFT
            basePerp = GeoUtils.perpendicularVector(p[currPos], perp1,
                                                    roadWidth, toLeft)
            toLeft = computeOrientation(p[currPos], basePerp,
                                        p[currPos + 1]) == LEFT
            radians = Angle.angleBetween(center, p[currPos], p[currPos + 1])

            if circularArc:
                #left edge
                if toLeft:
                    angle = -Angle.toDegrees(radians)
                    ratio = (radius - _laneWidths[currPos]) / radius
                else:
                    angle = Angle.toDegrees(radians)
                    ratio = (radius + _laneWidths[currPos]) / radius
                arc = Arc(center, p[currPos], angle)
                arcPts = arc.getCoordinates()
                for pt in arcPts:
                    _roadCenterLine.add(pt)
                start = CU.add(
                    center, CU.multiply(ratio, CU.subtract(p[currPos],
                                                           center)))
                arc = Arc(center, start, angle)
                arcPts = arc.getCoordinates()
                for pt in arcPts:
                    roadEdgeLeft.add(pt)
                #right edge
                if toLeft:
                    ratio = (radius + _laneWidths[currPos]) / radius
                else:
                    ratio = (radius - _laneWidths[currPos]) / radius
                start = CU.add(
                    center, CU.multiply(ratio, CU.subtract(p[currPos],
                                                           center)))
                arc = Arc(center, start, angle)
                arcPts = arc.getCoordinates()
                for pt in arcPts:
                    roadEdgeRight.add(pt)
                perp1.x = center.x
                perp1.y = center.y
                _radius = radius - _laneWidths[currPos]
            else:  #smooth tangent non-circular curve
                #left edge
                if toLeft:
                    angle = -Angle.toDegrees(radians)
                else:
                    angle = Angle.toDegrees(radians)
                start = p[currPos]
                arc = Arc(center, start, angle)
                arcPts = arc.getCoordinates()
                for pt in arcPts:
                    _roadCenterLine.add(pt)
                inc = (_laneWidths[currPos + 1] -
                       _laneWidths[currPos]) / (arcPts.size() - 1)
                i = 0
                for pt in arcPts:
                    if toLeft:
                        ratio = (radius - _laneWidths[currPos] -
                                 (i * inc)) / radius
                    else:
                        ratio = (radius + _laneWidths[currPos] +
                                 (i * inc)) / radius
                    roadEdgeLeft.add(
                        CU.add(center,
                               CU.multiply(ratio, CU.subtract(pt, center))))
                    i += 1
                #right edge
                i = 0
                for pt in arcPts:
                    if toLeft:
                        ratio = (radius + _laneWidths[currPos] +
                                 (i * inc)) / radius
                    else:
                        ratio = (radius - _laneWidths[currPos] -
                                 (i * inc)) / radius
                    roadEdgeRight.add(
                        CU.add(center,
                               CU.multiply(ratio, CU.subtract(pt, center))))
                    i += 1
                perp1.x = center.x
                perp1.y = center.y
                _radius = radius - _laneWidths[currPos]
        else:  #construct straight section of road
            roadEdgeLeft.add(
                GeoUtils.perpendicularVector(p[currPos + 1], p[currPos],
                                             _laneWidths[currPos + 1], right))
            roadEdgeRight.add(
                GeoUtils.perpendicularVector(p[currPos + 1], p[currPos],
                                             _laneWidths[currPos + 1], left))
            perp1 = GeoUtils.perpendicularVector(p[currPos + 1], p[currPos],
                                                 _laneWidths[currPos + 1],
                                                 right)
            _roadCenterLine.add(p[currPos + 1])
            _radius = 0
        currPos += 1
    #if final:   #uncomment to display click point feedback for debugging
    p.clear()  #clear the click point array and replace with road edges
    for pt in roadEdgeLeft:
        p.add(pt)
    #trace right return path back to start
    i = roadEdgeRight.size() - 1
    while i >= 0:
        p.add(roadEdgeRight[i])
        i -= 1
def _roadDraw(p, final=0):
    global _edit1, _laneWidths, _doBackup, _skip, _radius, _roadCenterLine
    roadEdgeLeft = ArrayList()
    roadEdgeRight = ArrayList()
    _roadCenterLine = ArrayList()
    try:
        laneWidth = float(_edit1.text)
    except:
        laneWidth = p[0].distance(p[1])
    roadWidth = laneWidth * 2.0
    if p.size() == 3:
        _laneWidths = [laneWidth, laneWidth]
    _edit1.text = "%f" % laneWidth    
    p.remove(0)
    if len(_laneWidths) < p.size():
        _laneWidths.append(laneWidth)
    else:
        _laneWidths[-1] = laneWidth
    #handle the backup button
    for skip in _skip: p.remove(skip)
    skip = 0
    if _doBackup:
        skip = p.size() - 2  #index of prior point
        _skip.append(skip)   #we'll need it next time we get p[]
        _doBackup = 0
        if skip > 1:         #lane width skips can be handled now
            _laneWidths = _laneWidths[:skip] + _laneWidths[skip+1:]
    if skip > 1:
        p.remove(skip)
    left = 1
    right = 0
    #crank in the initial road rectangle left and right edges
    roadEdgeLeft.add(GeoUtils.perpendicularVector(p[0], p[1], _laneWidths[0], left))
    roadEdgeRight.add(GeoUtils.perpendicularVector(p[0], p[1], _laneWidths[0], left))
    roadEdgeRight.add(GeoUtils.perpendicularVector(p[0], p[1], _laneWidths[0], right))
    roadEdgeLeft.add(GeoUtils.perpendicularVector(p[1], p[0], _laneWidths[1], right))
    roadEdgeRight.add(GeoUtils.perpendicularVector(p[1], p[0], _laneWidths[1], left))
    _roadCenterLine.add(p[0])
    _roadCenterLine.add(p[1])
    #calculate the left and right edges of the rest of the road
    currPos = 1
    endPos = p.size() - 1 #the last point in the array is the curr mouse pos adjusted by constraints
    perp1 = GeoUtils.perpendicularVector(p[1], p[0], roadWidth, right) 
    while currPos < endPos:
        midPt = CU.add( p[currPos], CU.divide(CU.subtract(p[currPos + 1], p[currPos]), 2))
        perp2 = GeoUtils.perpendicularVector(midPt, p[currPos], roadWidth, right)
        center = GeoUtils.getIntersection(p[currPos], perp1, midPt, perp2)
        if center.z == 0.0:  #check for parallel vectors
            radius = center.distance(p[currPos])
            d = p[currPos].distance(midPt)
            curved = radius / d < 50  #compare to tangent threshold
        else: curved = 0
        if curved: #construct a circular curve
            circularArc = (_laneWidths[currPos] == _laneWidths[currPos + 1])
            radius = center.distance(p[currPos])
            toLeft = computeOrientation(p[currPos], perp1, p[currPos + 1]) == LEFT
            basePerp = GeoUtils.perpendicularVector(p[currPos], perp1, roadWidth, toLeft)
            toLeft = computeOrientation(p[currPos], basePerp, p[currPos + 1]) == LEFT 
            radians = Angle.angleBetween(center, p[currPos], p[currPos + 1])
            
            if circularArc:
                #left edge
                if toLeft:
                    angle = -Angle.toDegrees(radians)
                    ratio = (radius - _laneWidths[currPos]) / radius
                else:
                    angle = Angle.toDegrees(radians)
                    ratio = (radius + _laneWidths[currPos]) / radius
                arc = Arc(center, p[currPos], angle)
                arcPts = arc.getCoordinates()
                for pt in arcPts:
                    _roadCenterLine.add(pt)
                start = CU.add(center, CU.multiply(ratio, CU.subtract(p[currPos], center)))
                arc = Arc(center, start, angle)
                arcPts = arc.getCoordinates()
                for pt in arcPts:
                    roadEdgeLeft.add(pt)
                #right edge 
                if toLeft:
                    ratio = (radius + _laneWidths[currPos]) / radius
                else:
                    ratio = (radius - _laneWidths[currPos]) / radius
                start = CU.add(center, CU.multiply(ratio, CU.subtract(p[currPos], center)))
                arc = Arc(center, start, angle)
                arcPts = arc.getCoordinates()
                for pt in arcPts:
                    roadEdgeRight.add(pt)
                perp1.x = center.x
                perp1.y = center.y
                _radius = radius - _laneWidths[currPos]
            else: #smooth tangent non-circular curve
                #left edge
                if toLeft:
                    angle = -Angle.toDegrees(radians)
                else:
                    angle = Angle.toDegrees(radians)
                start = p[currPos]
                arc = Arc(center, start, angle)
                arcPts = arc.getCoordinates()
                for pt in arcPts:
                    _roadCenterLine.add(pt)
                inc = (_laneWidths[currPos + 1] - _laneWidths[currPos]) / (arcPts.size() - 1)
                i = 0
                for pt in arcPts:
                    if toLeft:
                        ratio = (radius - _laneWidths[currPos]  - (i * inc)) / radius
                    else:
                        ratio = (radius +  _laneWidths[currPos] + (i * inc)) / radius
                    roadEdgeLeft.add(CU.add(center, CU.multiply(ratio, CU.subtract(pt, center))))
                    i += 1
                #right edge
                i = 0
                for pt in arcPts:
                    if toLeft:
                        ratio = (radius + _laneWidths[currPos] + (i * inc)) / radius
                    else:
                        ratio = (radius - _laneWidths[currPos] - (i * inc)) / radius
                    roadEdgeRight.add(CU.add(center, CU.multiply(ratio, CU.subtract(pt, center))))
                    i += 1
                perp1.x = center.x
                perp1.y = center.y
                _radius = radius - _laneWidths[currPos]
        else: #construct straight section of road
            roadEdgeLeft.add(GeoUtils.perpendicularVector(p[currPos + 1], p[currPos], _laneWidths[currPos + 1], right))
            roadEdgeRight.add(GeoUtils.perpendicularVector(p[currPos + 1], p[currPos], _laneWidths[currPos + 1], left))
            perp1 = GeoUtils.perpendicularVector(p[currPos + 1], p[currPos], _laneWidths[currPos + 1], right)
            _roadCenterLine.add(p[currPos + 1])
            _radius = 0
        currPos += 1
    #if final:   #uncomment to display click point feedback for debugging
    p.clear()    #clear the click point array and replace with road edges
    for pt in roadEdgeLeft:
        p.add(pt)
    #trace right return path back to start
    i = roadEdgeRight.size() - 1
    while i >= 0:
        p.add(roadEdgeRight[i])
        i -= 1