Skip to main content
Question

Create arc from 2 points and a radius


Forum|alt.badge.img

Hi FME Community,

I'm trying to create an arc from two Points and a radius:

The radius can be concave or convex depending on the radius sign (negative or positive)

Anyone got any ideas how that can be done using FME?

Thanks in advance

4 replies

takashi
Contributor
Forum|alt.badge.img+19
  • Contributor
  • March 8, 2019

Hi, the FMEArc class from Python FME Objects API has a constructor which creates an Arc instance from two points, radius and whether to create counter-clockwise. See the API document.

init(twoPoints, radius, counterClockwise)

Creates an arc using the 2 points contained in the tuple, and the supplied ‘radius’ and points. startPoint and endPoint (twoPoints[0and twoPoints[1]) must not be None.

Parameters:    
twoPoints (tuple[FMEPoint]) – The tuple containing 2 points to create the arc in the form (startPoint, endPoint).
radius (float) – The radius value for the arc to be created.
counterClockwise (bool) – Whether to create a counter-clockwise arc.

 

A PythonCaller with this script might help you.

import fmeobjects
def createArc(feature):
    x1 = float(feature.getAttribute('X1'))
    y1 = float(feature.getAttribute('Y1'))
    x2 = float(feature.getAttribute('X2'))
    y2 = float(feature.getAttribute('Y2'))
    twoPoints = (fmeobjects.FMEPoint(x1, y1), fmeobjects.FMEPoint(x2, y2))
    radius = float(feature.getAttribute('Radius'))
    feature.setGeometry(fmeobjects.FMEArc(twoPoints, abs(radius), 0 < radius))

 


Forum|alt.badge.img
  • Author
  • March 8, 2019
takashi wrote:

Hi, the FMEArc class from Python FME Objects API has a constructor which creates an Arc instance from two points, radius and whether to create counter-clockwise. See the API document.

init(twoPoints, radius, counterClockwise)

Creates an arc using the 2 points contained in the tuple, and the supplied ‘radius’ and points. startPoint and endPoint (twoPoints[0and twoPoints[1]) must not be None.

Parameters:    
twoPoints (tuple[FMEPoint]) – The tuple containing 2 points to create the arc in the form (startPoint, endPoint).
radius (float) – The radius value for the arc to be created.
counterClockwise (bool) – Whether to create a counter-clockwise arc.

 

A PythonCaller with this script might help you.

import fmeobjects
def createArc(feature):
    x1 = float(feature.getAttribute('X1'))
    y1 = float(feature.getAttribute('Y1'))
    x2 = float(feature.getAttribute('X2'))
    y2 = float(feature.getAttribute('Y2'))
    twoPoints = (fmeobjects.FMEPoint(x1, y1), fmeobjects.FMEPoint(x2, y2))
    radius = float(feature.getAttribute('Radius'))
    feature.setGeometry(fmeobjects.FMEArc(twoPoints, abs(radius), 0 < radius))

 

Hi, and thanks @takashi

Will that work if radius is set to large number as 3000?


takashi
Contributor
Forum|alt.badge.img+19
  • Contributor
  • March 8, 2019
takashi wrote:

Hi, the FMEArc class from Python FME Objects API has a constructor which creates an Arc instance from two points, radius and whether to create counter-clockwise. See the API document.

init(twoPoints, radius, counterClockwise)

Creates an arc using the 2 points contained in the tuple, and the supplied ‘radius’ and points. startPoint and endPoint (twoPoints[0and twoPoints[1]) must not be None.

Parameters:    
twoPoints (tuple[FMEPoint]) – The tuple containing 2 points to create the arc in the form (startPoint, endPoint).
radius (float) – The radius value for the arc to be created.
counterClockwise (bool) – Whether to create a counter-clockwise arc.

 

A PythonCaller with this script might help you.

import fmeobjects
def createArc(feature):
    x1 = float(feature.getAttribute('X1'))
    y1 = float(feature.getAttribute('Y1'))
    x2 = float(feature.getAttribute('X2'))
    y2 = float(feature.getAttribute('Y2'))
    twoPoints = (fmeobjects.FMEPoint(x1, y1), fmeobjects.FMEPoint(x2, y2))
    radius = float(feature.getAttribute('Radius'))
    feature.setGeometry(fmeobjects.FMEArc(twoPoints, abs(radius), 0 < radius))

 

No problem for large radius.

It doesn't work only when the absolute value of radius is less than half of the distance between two points.


Forum|alt.badge.img
  • Author
  • March 8, 2019

Got a reply from one of my collegues (thanks Daniel Kroon) which gives a very good result:

0684Q00000ArLY8QAN.png

  

import fme

 

import fmeobjects

 

import math 

def processFeature(feature):

 

    """Set the geometry of the feature, either as arc or line, depending on specified Radius.

 

 

 

    Expects the following feature attributes to be present: 'X1','Y1','X2','Y2','Radius'

 

 

 

    Zero radius creates and sets a line-geometry

 

    Positive radius creates a counter-clockwise arc-geometry.

 

    Negative radius creates a clockwise arc-geometry.

 

 

 

    Feature attribute _used_arc_radius contains the actual radius being used when creating the geometry.

 

    """

 

 

 

    # Get coordinates and radius from feature attributes

 

    coords = tuple(map(lambda c: float(feature.getAttribute(c)), ['X1','Y1','X2','Y2']))

 

    radius = float(feature.getAttribute('Radius'))

 

 

 

    # Create an arc if radius is other than 0, else create a straight line

 

    if(abs(radius)):

 

        # Create point geometry

 

        twoPoints = tuple(map(lambda c: fmeobjects.FMEPoint(*c), zip(coords[::2],coords[1::2])))

 

 

 

        # Calculate the minimul allowed radius for an arc given two points

 

        min_allowed_radius = round(math.sqrt((coords[0]-coords[2])**2+(coords[1]-coords[3])**2)/2,0)

 

 

 

        # Create and set arc geometery

 

        use_arc_radius = max(abs(radius),min_allowed_radius)

 

 

 

        feature.setGeometry(fmeobjects.FMEArc(twoPoints, use_arc_radius, 0 > radius))

 

        feature.setAttribute('_used_arc_radius',use_arc_radius)

 

 

 

    else:

 

        # Create and set arc geometery

 

        feature.setGeometry(fmeobjects.FMELine(list(zip(coords[::2],coords[1::2]))))

 

        feature.setAttribute('_used_arc_radius',0)

Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings