# CappedSphere

VTKExamples/Python/Modelling/CappedSphere

### Description¶

Demonstrates how to create a capped sphere.

Firstly a line is created in the x-z plane corresponding to an arc from +z to -z in the +x direction in the x-z plane, the length of the arc is specified in degrees.

Then the line is extended by dropping a perpendicular to the x-axis.

The points generated are then converted to a line and passed through to the vtkRotationalExtrusionFilter to generate the resultant 3D surface.

The parameters are:

• angle - the arc length in degrees default 90° (a hemisphere)
• step -the step size of the arc in degrees, default 1°

Options are provided to:

• Uncap the sphere (-u, --uncapped)
• Display the line that was rotationally extruded (-s, --show_line)

Note

The coordinate system for specifying the arc is left-handed with 0° aligned with the positive z-axis, 90° aligned with the positive x-axis.

Note

You can substitute different parametric equations for x and z in the line generating function to get other shapes.

Other Languages

See (Cxx)

Question

### Code¶

CappedSphere.py

#!/usr/bin/env python

import math

import vtk

def get_program_parameters():
import argparse
description = 'Display a capped sphere.'
epilogue = '''
'''
parser = argparse.ArgumentParser(description=description, epilog=epilogue,
formatter_class=argparse.RawDescriptionHelpFormatter)
help='The length of the arc in degrees from +z to -z in the +x direction in the x-z plane.')
parser.add_argument('step', default=1, type=float, nargs='?', help='Step size in degrees.')
parser.add_argument('-u', '--uncapped', action='store_true', help='Uncap the sphere.')
help='Show the line that is rotationally extruded to make the surface.')
args = parser.parse_args()
return args.angle, args.step, args.radius, args.uncapped, args.show_line

def main():
angle, step, radius, uncapped, show_line = get_program_parameters()
# With default settings set this to 45 and you get a bowl with a flat bottom.

pts = get_line(angle, step, radius, uncapped, start)

# Setup points and lines
points = vtk.vtkPoints()
lines = vtk.vtkCellArray()
for pt in pts:
pt_id = points.InsertNextPoint(pt)
if pt_id < len(pts) - 1:
line = vtk.vtkLine()
line.GetPointIds().SetId(0, pt_id)
line.GetPointIds().SetId(1, pt_id + 1)
lines.InsertNextCell(line)

polydata = vtk.vtkPolyData()
polydata.SetPoints(points)
polydata.SetLines(lines)

# Extrude the profile to make the capped sphere
extrude = vtk.vtkRotationalExtrusionFilter()
extrude.SetInputData(polydata)
extrude.SetResolution(60)

#  Visualize
colors = vtk.vtkNamedColors()

# To see the line
lineMapper = vtk.vtkPolyDataMapper()
lineMapper.SetInputData(polydata)

lineActor = vtk.vtkActor()
lineActor.SetMapper(lineMapper)
lineActor.GetProperty().SetLineWidth(4)
lineActor.GetProperty().SetColor(colors.GetColor3d("Red"))

# To see the surface
surfaceMapper = vtk.vtkPolyDataMapper()
surfaceMapper.SetInputConnection(extrude.GetOutputPort())

surfaceActor = vtk.vtkActor()
surfaceActor.SetMapper(surfaceMapper)
surfaceActor.GetProperty().SetColor(colors.GetColor3d('Khaki'))

ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)

if show_line:
ren.SetBackground(colors.GetColor3d('LightSlateGray'))

ren.ResetCamera()
ren.GetActiveCamera().Azimuth(0)
ren.GetActiveCamera().Elevation(60)
ren.ResetCameraClippingRange()

renWin.SetSize(600, 600)
renWin.Render()
renWin.SetWindowName('CappedSphere')
iren.Start()

def get_line(angle, step, radius, uncapped, start):
"""
Get the points for a line.

:param angle: Length of the arc in degrees.
:param step: Step size in degrees.
:param uncapped: True if uncapped.
:param start: Starting angle.
:return: A vector of points.
"""
precision = 1.0e-6
pts = list()
# Do the curved line
theta = 0.0
while theta <= angle:
x = radius * math.cos(start - theta)
z = radius * math.sin(theta - start)
if x < 0:
x = 0
pts.append((x, 0, z))
break
if abs(x) < precision:
x = 0
if abs(z) < precision:
z = 0
pts.append((x, 0, z))
theta += step

if not uncapped:
# Drop a perpendicular from the last point to the x-axis
if len(pts) > 1:
if pts[-1][0] > 0:
last_point = pts[-1]
num_pts = 10
for i in range(1, num_pts):
x = last_point[0] - i / interval
z = last_point[2]
if x < 0:
x = 0
pts.append((x, 0, z))
break
if abs(x) < precision:
x = 0
if abs(z) < precision:
z = 0
pts.append((x, 0, z))
if pts[-1][0] > precision:
pts.append((0, 0, pts[-1][2]))
return pts

if __name__ == '__main__':
main()