Skip to content

Instantly share code, notes, and snippets.

@mrivlin
Forked from o8ruza8o/CutCircularArc.json
Last active November 24, 2023 21:18
Show Gist options
  • Save mrivlin/4bd6f29bedaec07b8e36 to your computer and use it in GitHub Desktop.
Save mrivlin/4bd6f29bedaec07b8e36 to your computer and use it in GitHub Desktop.
Plethora Computational Geometry Technical Exercise

Plethora Technical Exercise

The aim of this exercise is to test your ability to write clean, well structured code and to solve a basic problem inspired by systems we have built here at Plethora. When evaluating these challenges, we care both about the structure and correctness of your solution. Feel free to choose any imperative, object-oriented language that is freely available.

Your task is to automate quoting for parts manufactured with a 2-axis laser cutting machine. When a design is submitted by a user for laser cutting it is automatically converted to a 2D profile. This profile is the input to your system.

Profile Representation

A profile contains a set of edges, each of which derive from a type of curve. Edges adjoin to one another at vertices so that each edge has one or two vertex endpoints. Each edge and vertex element is keyed by a unique integer, id. A profile is stored in a JSON file that is organized like Schema.json.

We will consider two types of curve in this exercise: straight line segments and circular arcs. While a line segment is completely defined via its vertices, circular arcs contain the additional Center and ClockwiseFrom fields. The ClockwiseFrom field references the vertex from which the circular arc may be drawn clockwise until it reaches the other vertex of that edge.

The units for all curves is inches.

Quoting

The main considerations to be taken into account when quoting a part are material costs and machine costs.

Material costs are proportional to the area of stock used for the part with optimal stock orientation. Stock is pre cut into a rectangular shape where, to account for kerf thickness from the laser, additional padding is added to the design's bounds in each axis to define stock size.

Machine costs are proportional to the time the laser spends cutting. The laser is considered to travel in a straight line at the maximal laser cutting speed, v_max, but for a circular arc of nonzero radius, R, travels at a speed given by v_max * exp(-1/R).

Task

(1) Write code to deserialize extrusion profiles so that they can be represented in memory.

(2) Write a program that takes a profile and produces a quote. Assume:

- Padding: 0.1in

- Material Cost: $0.75/in^2

- Maximal laser cutter speed: 0.5 in/s

- Machine Time Cost: $0.07/s

(3) Keep all of your progress in a git repository and when you are done, push your repository and send an email letting us know you're done.

(4) Include a brief description of how to use your code, what you would do to improve it if you had more time and any other considerations you think are relevant. Please make sure to reference any external code or libraries used.

Examples

The provided examples are given for your convenience and testing. These examples represent a few very simple cases but expect your code to be tested with instances of more complex geometry.

Three example JSON files:

(1) Rectangle.json - a simple 3in x 5in rectangle.

Your program should output: 14.10 dollars

(2) ExtrudeCircularArc.json - a 2in x 1in rectangle with semi-circle added onto one of the 1in sides.

Your program should output: 4.47 dollars

(3) CutCircularArc.json - a 2in x 1in rectangle with semi-circle cut into one of the 1in sides.

Your program should output: 4.06 dollars

{
"Edges": {
"53330552": {
"Type": "LineSegment",
"Vertices": [
10212927,
43495525
]
},
"24807479": {
"Type": "CircularArc",
"Vertices": [
43495525,
55915408
],
"Center": {
"X": 2.0,
"Y": 0.5
},
"ClockwiseFrom": 43495525
},
"21940722": {
"Type": "LineSegment",
"Vertices": [
55915408,
63248778
]
},
"32368095": {
"Type": "LineSegment",
"Vertices": [
63248778,
10212927
]
}
},
"Vertices": {
"10212927": {
"Position": {
"X": 0.0,
"Y": 0.0
}
},
"43495525": {
"Position": {
"X": 2.0,
"Y": 0.0
}
},
"55915408": {
"Position": {
"X": 2.0,
"Y": 1.0
}
},
"63248778": {
"Position": {
"X": 0.0,
"Y": 1.0
}
}
}
}
{
"Edges": {
"5903470": {
"Type": "LineSegment",
"Vertices": [
53131231,
46104728
]
},
"8419032": {
"Type": "CircularArc",
"Vertices": [
46104728,
12289376
],
"Center": {
"X": 2.0,
"Y": 0.5
},
"ClockwiseFrom": 12289376
},
"8662426": {
"Type": "LineSegment",
"Vertices": [
12289376,
10852974
]
},
"30567910": {
"Type": "LineSegment",
"Vertices": [
10852974,
53131231
]
}
},
"Vertices": {
"53131231": {
"Position": {
"X": 0.0,
"Y": 0.0
}
},
"46104728": {
"Position": {
"X": 2.0,
"Y": 0.0
}
},
"12289376": {
"Position": {
"X": 2.0,
"Y": 1.0
}
},
"10852974": {
"Position": {
"X": 0.0,
"Y": 1.0
}
}
}
}
{
"Edges": {
"33476626": {
"Type": "LineSegment",
"Vertices": [
32854180,
27252167
]
},
"43942917": {
"Type": "LineSegment",
"Vertices": [
27252167,
59941933
]
},
"2606490": {
"Type": "LineSegment",
"Vertices": [
59941933,
23458411
]
},
"9799115": {
"Type": "LineSegment",
"Vertices": [
23458411,
32854180
]
}
},
"Vertices": {
"32854180": {
"Position": {
"X": 0.0,
"Y": 0.0
}
},
"27252167": {
"Position": {
"X": 0.0,
"Y": 3.0
}
},
"59941933": {
"Position": {
"X": 5.0,
"Y": 3.0
}
},
"23458411": {
"Position": {
"X": 5.0,
"Y": 0.0
}
}
}
}
{
"Edges": {
"id" : {
"id": "int",
"Type": "LineSegment",
"Vertices": ["int"],
},
"id" : {
"id": "int",
"Type": "CircularArc",
"Center": {
"X": "double",
"Y": "double",
},
"ClockwiseFrom": "int",
"Vertices": ["int"],
}
},
"Vertices": {
"id" : {
"id" : "int",
"Position": {
"X": "double",
"Y": "double",
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment