Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Oct 8, 2025

Fixed the broken scaled() behavior in Sphere, Cylinder, and Capsule classes by adding a scaled() method to the Shape base class. This eliminates code duplication and provides a consistent implementation for all shapes that support uniform scaling.

Additionally, added missing scale() implementations for Cone and Torus classes to support uniform scaling that preserves proportions.

Problem

Calling scaled() on Sphere, Cylinder, or Capsule objects resulted in a TypeError:

from compas.geometry import Sphere

c = Sphere(10)
scaled_c = c.scaled(0.5)
# TypeError: Sphere.scale() got an unexpected keyword argument 'x'

The base class Geometry.scaled() method calls scale(x=x, y=y, z=z) with keyword arguments to support non-uniform scaling. However, Sphere, Cylinder, and Capsule override the scale() method to only accept a single factor parameter for uniform scaling (since non-uniform scaling would change the fundamental nature of these primitive shapes).

Solution

  1. Added scaled() method to Shape base class that accepts a single factor parameter and calls the shape's scale(factor) method. This provides a consistent implementation for all shapes supporting uniform scaling.

  2. Added scale() implementations for Cone and Torus:

    • Cone: Scales both radius and height by the same factor
    • Torus: Scales both radius_axis and radius_pipe by the same factor

Changes Made

  • Added scaled(factor) method to Shape base class
  • Added scale(factor) method to Cone class
  • Added scale(factor) method to Torus class
  • Removed duplicate scaled() methods from Sphere, Cylinder, and Capsule classes
  • Added comprehensive tests for all shape scaling operations
  • Added CHANGELOG.md entry under "Unreleased > Changed" section

Scaling Behavior

All shape classes now support consistent scaling behavior:

  • scale(factor): Modifies the shape in place with uniform scaling
  • scaled(factor): Returns a scaled copy without modifying the original

Note: Box retains its custom scale(x, y, z) and scaled(x, y, z) methods to support non-uniform scaling.

Testing

  • ✅ All 16 scale-related tests pass
  • ✅ Original objects remain unchanged when using scaled()
  • ✅ Both scale() and scaled() work correctly for all shapes

Fixes #1488

Original prompt

This section details on the original issue you should resolve

<issue_title>Broken behaviour with Sphere.scaled()</issue_title>
<issue_description>Sphere.scaled() calls the scale() function with keyword arguments for x,y and z. However, the inbuilt Sphere.scale() method requires only a factor for uniform scaling of the self.radius. This makes it not possible to use the scaled() method at all. I suspect similar behaviour in the Cylinder class due to similar implementation of scale.

To replicate, create any sphere and apply scaling:
c = Sphere(10)
scaled_c = c.scaled(0.5,10,10)

  File "C:\Users\akango\Documents\github\compas_introduction_2025\.venv\lib\site-packages\compas\geometry\geometry.py", line 173, in scaled
    geometry.scale(x=x, y=y, z=z)
TypeError: scale() got an unexpected keyword argument 'x'

Is there a reason why most Shape objects have their own transformation methods which are different from the methods it could inherit from Geometry?

</issue_description>

<agent_instructions>Please provide a fix to this, the problem seems to be that scaled will internally call scale, and Sphere overrides scale() with different params, so, scaled should probably also be overriden with a Sphere-specific method</agent_instructions>

Comments on the Issue (you are @copilot in this section)

Fixes #1488

💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

@Copilot Copilot AI changed the title [WIP] Fix broken behaviour with Sphere.scaled() method Fix broken behavior with Sphere.scaled(), Cylinder.scaled(), and Capsule.scaled() Oct 8, 2025
Copilot finished work on behalf of gonzalocasas October 8, 2025 23:35
@Copilot Copilot AI requested a review from gonzalocasas October 8, 2025 23:35
Copy link

codecov bot commented Oct 8, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 62.13%. Comparing base (b8cef0d) to head (2fe0681).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1489      +/-   ##
==========================================
+ Coverage   62.00%   62.13%   +0.13%     
==========================================
  Files         208      208              
  Lines       22427    22437      +10     
==========================================
+ Hits        13905    13942      +37     
+ Misses       8522     8495      -27     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@gonzalocasas gonzalocasas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good! But @copilot : please add a CHANGELOG.md entry

@gonzalocasas
Copy link
Member

@copilot please address the review finding above

Copy link
Contributor Author

Copilot AI commented Oct 9, 2025

@copilot please address the review finding above

Added CHANGELOG.md entry in commit eb9d62e.

@Copilot Copilot AI requested a review from gonzalocasas October 9, 2025 00:10
Copilot finished work on behalf of gonzalocasas October 9, 2025 00:11
@gonzalocasas gonzalocasas marked this pull request as ready for review October 9, 2025 06:01
Copy link
Member

@gonzalocasas gonzalocasas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lgtm

@gonzalocasas
Copy link
Member

@tomvanmele does this look good to you as a fix?

Copy link
Member

@gonzalocasas gonzalocasas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot please move the scaled() implementation to the base class Shape so that it's not repeated 3 times

Copy link
Contributor Author

Copilot AI commented Oct 15, 2025

@copilot please move the scaled() implementation to the base class Shape so that it's not repeated 3 times

Moved scaled() implementation to the Shape base class in commit bd0252b. This eliminates the duplication across Sphere, Cylinder, and Capsule classes.

Copilot finished work on behalf of gonzalocasas October 15, 2025 12:29
@Copilot Copilot AI requested a review from gonzalocasas October 15, 2025 12:29
@tomvanmele
Copy link
Member

should we remove Box.scaled? perhaps it makes sense that scaling of a shape always preserves the proportions of the geometry, also in the case of the box...

@tomvanmele
Copy link
Member

should we also add the missing implementations of scale for Cone and Torus?
or should that go into separate PRs?

@gonzalocasas
Copy link
Member

Let's add scale for Cone and Torus here. About removing scaled from Box, I would keep it for now, I think it's actually useful, and removing it actually feels a tad annoying despite the minor misalignment in API of shapes.

@gonzalocasas
Copy link
Member

@copilot please add scale implementations (preserving proportions) to Cone and Torus as well

Copy link
Contributor Author

Copilot AI commented Oct 15, 2025

@copilot please add scale implementations (preserving proportions) to Cone and Torus as well

Added scale() implementations for Cone and Torus that preserve proportions (uniform scaling) in commit 42c1b71. Both implementations scale all dimensional parameters by the same factor, and comprehensive tests have been added.

@Copilot Copilot AI changed the title Fix broken behavior with Sphere.scaled(), Cylinder.scaled(), and Capsule.scaled() Fix broken behavior with Sphere.scaled(), Cylinder.scaled(), and Capsule.scaled() and add scale() for Cone and Torus Oct 15, 2025
Copilot finished work on behalf of gonzalocasas October 15, 2025 13:37
Copy link
Member

@gonzalocasas gonzalocasas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@gonzalocasas
Copy link
Member

@tomvanmele what do you think? good to go?

@tomvanmele
Copy link
Member

go for it

@gonzalocasas gonzalocasas merged commit 43cb6b6 into main Oct 15, 2025
33 checks passed
@gonzalocasas gonzalocasas deleted the copilot/fix-sphere-scaled-method branch October 15, 2025 16:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Broken behaviour with Sphere.scaled()

3 participants