diff --git a/.classpath b/.classpath
index 8727917..fb50116 100644
--- a/.classpath
+++ b/.classpath
@@ -1,6 +1,6 @@
-
+
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
index 416f4fb..b1081a4 100644
--- a/.settings/org.eclipse.jdt.core.prefs
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -1,11 +1,307 @@
eclipse.preferences.version=1
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.source=1.8
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=false
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=120
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
+org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..1ebb3e9
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,22 @@
+The MIT License
+
+Copyright 2019 David Dunn & Erik Colban
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1b0fe19
--- /dev/null
+++ b/README.md
@@ -0,0 +1,43 @@
+# Project Description
+
+This project allows novice programmers to experience a quick and easy start to programming. An example of a very simple program is as follows:
+
+ import Robot;
+
+ public class RobotExample
+ {
+
+ public static void main(String[] args) throws InterruptedException
+ {
+ Robot rob = new Robot();
+ rob.setSpeed(5);
+ rob.penDown();
+ rob.move(100);
+ rob.turn(90);
+ }
+ }
+
+
+This program will bring up a window with the image of a robot in it. The robot moves 100 points while drawing a line, turns 90 degrees, and stops. With small variations, the programmer can make the robot make more intricate movements and draw more intricate patterns. `RobotExample1` and `RobotExample4` show examples slightly more complex. These examples also illustrate the use of for-loops.
+
+A robot can also be controlled via the keys on the keyboard by adding a `KeyboardAdapter`. `RobotExample2` is a very small program, which lets the user control the robot via up, down, left and right arrow key presses. `ExtendedKeyboardAdapter` shows an extension of `KeyboardAdapter` that adds further commands that can be invoked through the key presses. In `RobotExample3`, the use of `ExtendedKeyboardAdapter` is illustrated. This example also shows how to use any image as the robot image.
+
+More than one robot can be added to the window, which is illustrated by `RobotExample5`. This example also shows how to make the robots run simultaneously by letting the robots run in different threads.
+
+`RobotExample6` shows how to control two robots separately from the keyboard using `ShiftKeyboardAdapter`s. When the user holds down the shift key, one robot reacts to the key events, otherwise the other robot reacts to the key events.
+
+If a user wants to teach a `Robot` new tricks, it is possible to extend the `Robot` class and add new methods and/or override existing ones. This is illustrated by `MyRobot`, which can draw regular polygons. The usage is shown in `RobotExample8`. Alternatively to extension, composition may be used. The class `Driver` has a `Robot` instance and commands to the `Driver` instance are delegated to the `Robot` instance. The usage is illustrated by `RobotExample9`. As one can see, `RobotExample8` and `RobotExample9` are almost identical.
+
+Robots don't necessary have to move in straight lines. `RobotExample11.java` illustrates the use of `quadTo()` and `cubicTo()` to make robots move along quadratic and cubic paths. `RobotExample12.java` illustrates the command `followPath()` that takes a `PathIterator` as argument.
+
+# Importing the jar file
+
+Download this [jar file](https://github.com/ecolban/Robot/blob/master/jar/robot.jar?raw=true) and add it to the build path of your project. This jar file also contains the API documentation in the folder named `doc`.
+
+
+
+
+
+
+
+
diff --git a/Robot.iml b/Robot.iml
new file mode 100644
index 0000000..d6dade6
--- /dev/null
+++ b/Robot.iml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/doc/allclasses-frame.html b/doc/allclasses-frame.html
new file mode 100644
index 0000000..8eb2118
--- /dev/null
+++ b/doc/allclasses-frame.html
@@ -0,0 +1,32 @@
+
+
+
+
+
+All Classes
+
+
+
+
+
+All Classes
+
+
+
diff --git a/doc/allclasses-noframe.html b/doc/allclasses-noframe.html
new file mode 100644
index 0000000..353a3dd
--- /dev/null
+++ b/doc/allclasses-noframe.html
@@ -0,0 +1,32 @@
+
+
+
+
+
+All Classes
+
+
+
+
+
+All Classes
+
+
+
diff --git a/doc/constant-values.html b/doc/constant-values.html
new file mode 100644
index 0000000..e019d1d
--- /dev/null
+++ b/doc/constant-values.html
@@ -0,0 +1,122 @@
+
+
+
+
+
+Constant Field Values
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/deprecated-list.html b/doc/deprecated-list.html
new file mode 100644
index 0000000..6d03bf3
--- /dev/null
+++ b/doc/deprecated-list.html
@@ -0,0 +1,149 @@
+
+
+
+
+
+Deprecated List
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/help-doc.html b/doc/help-doc.html
new file mode 100644
index 0000000..2b54328
--- /dev/null
+++ b/doc/help-doc.html
@@ -0,0 +1,223 @@
+
+
+
+
+
+API Help
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+Overview
+The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.
+
+
+Package
+Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:
+
+Interfaces (italic)
+Classes
+Enums
+Exceptions
+Errors
+Annotation Types
+
+
+
+Class/Interface
+Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:
+
+Class inheritance diagram
+Direct Subclasses
+All Known Subinterfaces
+All Known Implementing Classes
+Class/interface declaration
+Class/interface description
+
+
+Nested Class Summary
+Field Summary
+Constructor Summary
+Method Summary
+
+
+Field Detail
+Constructor Detail
+Method Detail
+
+Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
+
+
+Annotation Type
+Each annotation type has its own separate page with the following sections:
+
+Annotation Type declaration
+Annotation Type description
+Required Element Summary
+Optional Element Summary
+Element Detail
+
+
+
+Enum
+Each enum has its own separate page with the following sections:
+
+Enum declaration
+Enum description
+Enum Constant Summary
+Enum Constant Detail
+
+
+
+Tree (Class Hierarchy)
+There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.
+
+When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
+When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
+
+
+
+Deprecated API
+The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
+
+
+Index
+The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
+
+
+Prev/Next
+These links take you to the next or previous class, interface, package, or related page.
+
+
+Frames/No Frames
+These links show and hide the HTML frames. All pages are available with or without frames.
+
+
+All Classes
+The All Classes link shows all classes and interfaces except non-static nested types.
+
+
+Serialized Form
+Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
+
+
+Constant Field Values
+The Constant Field Values page lists the static final fields and their values.
+
+
+
This help file applies to API documentation generated using the standard doclet.
+
+
+
+
+
+
diff --git a/doc/index-files/index-1.html b/doc/index-files/index-1.html
new file mode 100644
index 0000000..e63801e
--- /dev/null
+++ b/doc/index-files/index-1.html
@@ -0,0 +1,159 @@
+
+
+
+
+
+A-Index
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A C D E F G H I K L M O P Q R S T U
+
+
+
A
+
+addKeyboardAdapter(KeyboardAdapter) - Method in class org.jointheleague.graphical.robot.Robot
+
+addKeyboardAdapter(KeyboardAdapter) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+
+
+addTo(Path2D) - Method in class org.jointheleague.graphical.robot.curves.Close
+
+addTo(Path2D, float) - Method in class org.jointheleague.graphical.robot.curves.Close
+
+addTo(Path2D) - Method in class org.jointheleague.graphical.robot.curves.Cubic
+
+addTo(Path2D, float) - Method in class org.jointheleague.graphical.robot.curves.Cubic
+
+addTo(Path2D) - Method in class org.jointheleague.graphical.robot.curves.Line
+
+addTo(Path2D, float) - Method in class org.jointheleague.graphical.robot.curves.Line
+
+addTo(Path2D) - Method in class org.jointheleague.graphical.robot.curves.Move
+
+addTo(Path2D, float) - Method in class org.jointheleague.graphical.robot.curves.Move
+
+addTo(Path2D) - Method in class org.jointheleague.graphical.robot.curves.Quad
+
+addTo(Path2D, float) - Method in class org.jointheleague.graphical.robot.curves.Quad
+
+addTo(Path2D) - Method in interface org.jointheleague.graphical.robot.curves.Segment
+
+Adds the Segment to the end of a Path2D
+
+addTo(Path2D, float) - Method in interface org.jointheleague.graphical.robot.curves.Segment
+
+Adds a sub-segment of this segment to the end of a Path2D
+
+
+
A C D E F G H I K L M O P Q R S T U
+
+
+
+
+
+
diff --git a/doc/index-files/index-10.html b/doc/index-files/index-10.html
new file mode 100644
index 0000000..bd8f88a
--- /dev/null
+++ b/doc/index-files/index-10.html
@@ -0,0 +1,143 @@
+
+
+
+
+
+L-Index
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A C D E F G H I K L M O P Q R S T U
+
+
+
L
+
+Line - Class in org.jointheleague.graphical.robot.curves
+
+Line(float, float, float[], int, Color) - Constructor for class org.jointheleague.graphical.robot.curves.Line
+
+Constructor
+
+lineTo(float, float, boolean) - Method in class org.jointheleague.graphical.robot.Robot
+
+lineTo(float, float, boolean) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Move the robot forward to a given position.
+
+loadDefaultRobi() - Static method in class org.jointheleague.graphical.robot.RobotImage
+
+loadImage(File) - Static method in class org.jointheleague.graphical.robot.RobotImage
+
+loadRobi(String) - Static method in class org.jointheleague.graphical.robot.RobotImage
+
+
+
A C D E F G H I K L M O P Q R S T U
+
+
+
+
+
+
diff --git a/doc/index-files/index-11.html b/doc/index-files/index-11.html
new file mode 100644
index 0000000..cb75aff
--- /dev/null
+++ b/doc/index-files/index-11.html
@@ -0,0 +1,171 @@
+
+
+
+
+
+M-Index
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A C D E F G H I K L M O P Q R S T U
+
+
+
M
+
+microMove(int) - Method in class org.jointheleague.graphical.robot.Robot
+
+microMove(int) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Makes the Robot move one step.
+
+microTurn(int) - Method in class org.jointheleague.graphical.robot.Robot
+
+microTurn(int) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Makes the Robot turn in place a small angle.
+
+miniaturize() - Method in class org.jointheleague.graphical.robot.Robot
+
+miniaturize() - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Makes the image of the Robot small
+
+Move - Class in org.jointheleague.graphical.robot.curves
+
+Move(float, float, float[]) - Constructor for class org.jointheleague.graphical.robot.curves.Move
+
+Constructor.
+
+move(int) - Method in class org.jointheleague.graphical.robot.Robot
+
+move(int) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Makes the robot move a given distance.
+
+moveTo(float, float) - Method in class org.jointheleague.graphical.robot.Robot
+
+Deprecated.
+
+moveTo(float, float, boolean, boolean) - Method in class org.jointheleague.graphical.robot.Robot
+
+moveTo(float, float) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+
+
+moveTo(float, float, boolean, boolean) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Move the Robot to a given position.
+
+
+
A C D E F G H I K L M O P Q R S T U
+
+
+
+
+
+
diff --git a/doc/index-files/index-12.html b/doc/index-files/index-12.html
new file mode 100644
index 0000000..52fc25f
--- /dev/null
+++ b/doc/index-files/index-12.html
@@ -0,0 +1,129 @@
+
+
+
+
+
+O-Index
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A C D E F G H I K L M O P Q R S T U
+
+
+
O
+
+org.jointheleague.graphical.robot - package org.jointheleague.graphical.robot
+
+org.jointheleague.graphical.robot.curves - package org.jointheleague.graphical.robot.curves
+
+
+
A C D E F G H I K L M O P Q R S T U
+
+
+
+
+
+
diff --git a/doc/index-files/index-13.html b/doc/index-files/index-13.html
new file mode 100644
index 0000000..d216189
--- /dev/null
+++ b/doc/index-files/index-13.html
@@ -0,0 +1,141 @@
+
+
+
+
+
+P-Index
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A C D E F G H I K L M O P Q R S T U
+
+
+
P
+
+paintComponent(Graphics) - Method in class org.jointheleague.graphical.robot.RobotWindow
+
+penDown() - Method in class org.jointheleague.graphical.robot.Robot
+
+penDown() - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Set the pen down, i.e., the Robot traces its movements with lines or curves.
+
+penUp() - Method in class org.jointheleague.graphical.robot.Robot
+
+penUp() - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Lifts the pen, i.e., the Robot stops drawing lines or curves.
+
+Pos(float, float) - Constructor for class org.jointheleague.graphical.robot.Robot.Pos
+
+
+
A C D E F G H I K L M O P Q R S T U
+
+
+
+
+
+
diff --git a/doc/index-files/index-14.html b/doc/index-files/index-14.html
new file mode 100644
index 0000000..1ed780f
--- /dev/null
+++ b/doc/index-files/index-14.html
@@ -0,0 +1,138 @@
+
+
+
+
+
+Q-Index
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A C D E F G H I K L M O P Q R S T U
+
+
+
Q
+
+Quad - Class in org.jointheleague.graphical.robot.curves
+
+Quad(float, float, float[], int, Color) - Constructor for class org.jointheleague.graphical.robot.curves.Quad
+
+Constructor
+
+quadTo(float, float, float, float, boolean) - Method in class org.jointheleague.graphical.robot.Robot
+
+quadTo(float, float, float, float, boolean) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Move the robot along a quadratic curve given by the robot's current position
+ and the control points (x1, y1) and (x2, y2).
+
+
+
A C D E F G H I K L M O P Q R S T U
+
+
+
+
+
+
diff --git a/doc/index-files/index-15.html b/doc/index-files/index-15.html
new file mode 100644
index 0000000..daf41f5
--- /dev/null
+++ b/doc/index-files/index-15.html
@@ -0,0 +1,169 @@
+
+
+
+
+
+R-Index
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A C D E F G H I K L M O P Q R S T U
+
+
+
R
+
+robot - Variable in class org.jointheleague.graphical.robot.KeyboardAdapter
+
+The Robot instance that the KeyboardAdapter is attached to.
+
+Robot - Class in org.jointheleague.graphical.robot
+
+
+ This class is used to show a robot inside a window.
+
+Robot() - Constructor for class org.jointheleague.graphical.robot.Robot
+
+Robot(int, int) - Constructor for class org.jointheleague.graphical.robot.Robot
+
+Instantiates a new default Robot at the position provided.
+
+Robot(String) - Constructor for class org.jointheleague.graphical.robot.Robot
+
+Instantiates a new Robot whose image is specified by the filename at the
+ center of the RobotWindow.
+
+Robot(BufferedImage) - Constructor for class org.jointheleague.graphical.robot.Robot
+
+Instantiates a new Robot at the center of the RobotWindow.
+
+Robot(String, int, int) - Constructor for class org.jointheleague.graphical.robot.Robot
+
+Robot(BufferedImage, int, int) - Constructor for class org.jointheleague.graphical.robot.Robot
+
+Robot.Pos - Class in org.jointheleague.graphical.robot
+
+RobotImage - Class in org.jointheleague.graphical.robot
+
+Utility class for loading images in robi format.
+
+RobotImage() - Constructor for class org.jointheleague.graphical.robot.RobotImage
+
+RobotInterface - Interface in org.jointheleague.graphical.robot
+
+RobotWindow - Class in org.jointheleague.graphical.robot
+
+Singleton class that defines the window in which the Robots move around.
+
+run() - Method in class org.jointheleague.graphical.robot.KeyboardAdapter
+
+
+
A C D E F G H I K L M O P Q R S T U
+
+
+
+
+
+
diff --git a/doc/index-files/index-16.html b/doc/index-files/index-16.html
new file mode 100644
index 0000000..533e328
--- /dev/null
+++ b/doc/index-files/index-16.html
@@ -0,0 +1,249 @@
+
+
+
+
+
+S-Index
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A C D E F G H I K L M O P Q R S T U
+
+
+
S
+
+Segment - Interface in org.jointheleague.graphical.robot.curves
+
+setAngle(double) - Method in class org.jointheleague.graphical.robot.Robot
+
+setAngle(double) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Set the robot's angle of orientation.
+
+setBackgroundImage(String) - Method in class org.jointheleague.graphical.robot.RobotWindow
+
+Set the RobotWindow's background Image.
+
+setMovingBackward(boolean) - Method in class org.jointheleague.graphical.robot.KeyboardAdapter
+
+Sets or unsets the Robot in a backward motion.
+
+setMovingForward(boolean) - Method in class org.jointheleague.graphical.robot.KeyboardAdapter
+
+Sets or unsets the Robot in a forward motion.
+
+setPenColor(Color) - Method in class org.jointheleague.graphical.robot.Robot
+
+setPenColor(int, int, int) - Method in class org.jointheleague.graphical.robot.Robot
+
+setPenColor(Color) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Sets the pen color
+
+setPenColor(int, int, int) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Sets the pen color given the red, green and blue components of the new
+ color.
+
+setPenWidth(int) - Method in class org.jointheleague.graphical.robot.Robot
+
+setPenWidth(int) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Sets the pen size.
+
+setPos(float, float) - Method in class org.jointheleague.graphical.robot.Robot
+
+setPos(float, float) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Set the position of the robot to (x, y) while maintaining its direction.
+
+setRandomPenColor() - Method in class org.jointheleague.graphical.robot.Robot
+
+setRandomPenColor() - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Sets the pen color to a random color.
+
+setRobot(Robot) - Method in class org.jointheleague.graphical.robot.KeyboardAdapter
+
+setSpeed(int) - Method in class org.jointheleague.graphical.robot.Robot
+
+setSpeed(int) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Sets the speed of the Robot.
+
+setTurningLeft(boolean) - Method in class org.jointheleague.graphical.robot.KeyboardAdapter
+
+Sets or unsets the Robot in a left turning motion.
+
+setTurningRight(boolean) - Method in class org.jointheleague.graphical.robot.KeyboardAdapter
+
+Sets or unsets the Robot in a left turning motion.
+
+setWinColor(Color) - Method in class org.jointheleague.graphical.robot.RobotWindow
+
+Set the RobotWindow's background Color.
+
+setWindowColor(Color) - Static method in class org.jointheleague.graphical.robot.Robot
+
+Sets the window's background color
+
+setWindowColor(int, int, int) - Static method in class org.jointheleague.graphical.robot.Robot
+
+Sets the window's background color given the red, green and blue
+ components of the new color.
+
+setWindowImage(String) - Static method in class org.jointheleague.graphical.robot.Robot
+
+Sets the window's background image
+
+setWindowSize(int, int) - Static method in class org.jointheleague.graphical.robot.Robot
+
+Sets the window size
+
+setWindowSize(int, int) - Method in class org.jointheleague.graphical.robot.RobotWindow
+
+Sets the dimension of the panel containing the robots.
+
+show() - Method in class org.jointheleague.graphical.robot.Robot
+
+show() - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Makes the Robot visible
+
+sleep(int) - Method in class org.jointheleague.graphical.robot.Robot
+
+sleep(int) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Waits a given number of milliseconds.
+
+sparkle() - Method in class org.jointheleague.graphical.robot.Robot
+
+sparkle() - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Makes the Robot sparkle.
+
+subSegment(float) - Method in class org.jointheleague.graphical.robot.curves.Close
+
+subSegment(float) - Method in class org.jointheleague.graphical.robot.curves.Cubic
+
+subSegment(float) - Method in class org.jointheleague.graphical.robot.curves.Line
+
+subSegment(float) - Method in class org.jointheleague.graphical.robot.curves.Move
+
+subSegment(float) - Method in class org.jointheleague.graphical.robot.curves.Quad
+
+subSegment(float) - Method in interface org.jointheleague.graphical.robot.curves.Segment
+
+Return the sub-segment of this segment that starts at 0 and ends at t.
+
+
+
A C D E F G H I K L M O P Q R S T U
+
+
+
+
+
+
diff --git a/doc/index-files/index-17.html b/doc/index-files/index-17.html
new file mode 100644
index 0000000..22e0532
--- /dev/null
+++ b/doc/index-files/index-17.html
@@ -0,0 +1,131 @@
+
+
+
+
+
+T-Index
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A C D E F G H I K L M O P Q R S T U
+
+
+
T
+
+turn(double) - Method in class org.jointheleague.graphical.robot.Robot
+
+turn(double) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Makes the Robot turn in place a given number of degrees.
+
+
+
A C D E F G H I K L M O P Q R S T U
+
+
+
+
+
+
diff --git a/doc/index-files/index-18.html b/doc/index-files/index-18.html
new file mode 100644
index 0000000..c4f550f
--- /dev/null
+++ b/doc/index-files/index-18.html
@@ -0,0 +1,131 @@
+
+
+
+
+
+U-Index
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A C D E F G H I K L M O P Q R S T U
+
+
+
U
+
+unSparkle() - Method in class org.jointheleague.graphical.robot.Robot
+
+unSparkle() - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Removes sparkles
+
+
+
A C D E F G H I K L M O P Q R S T U
+
+
+
+
+
+
diff --git a/doc/index-files/index-2.html b/doc/index-files/index-2.html
new file mode 100644
index 0000000..fd87f7b
--- /dev/null
+++ b/doc/index-files/index-2.html
@@ -0,0 +1,162 @@
+
+
+
+
+
+C-Index
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A C D E F G H I K L M O P Q R S T U
+
+
+
C
+
+changeRobot(BufferedImage) - Method in class org.jointheleague.graphical.robot.Robot
+
+changeRobot(String) - Method in class org.jointheleague.graphical.robot.Robot
+
+changeRobot(BufferedImage) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Changes the image of the Robot
+
+changeRobot(String) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Changes the image of the Robot
+
+clearDrawables() - Method in class org.jointheleague.graphical.robot.Robot
+
+clearDrawables() - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Removes all lines drawn by this Robot.
+
+Close - Class in org.jointheleague.graphical.robot.curves
+
+Close(float, float, float[], int, Color) - Constructor for class org.jointheleague.graphical.robot.curves.Close
+
+Constructor
+
+Cubic - Class in org.jointheleague.graphical.robot.curves
+
+Cubic(float, float, float[], int, Color) - Constructor for class org.jointheleague.graphical.robot.curves.Cubic
+
+Constructor
+
+cubicTo(float, float, float, float, float, float, boolean) - Method in class org.jointheleague.graphical.robot.Robot
+
+cubicTo(float, float, float, float, float, float, boolean) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Move the robot along a cubic curve given by the robot's current position
+ and the control points (x1, y1), (x2, y2) and (x3, y3).
+
+
+
A C D E F G H I K L M O P Q R S T U
+
+
+
+
+
+
diff --git a/doc/index-files/index-3.html b/doc/index-files/index-3.html
new file mode 100644
index 0000000..182af98
--- /dev/null
+++ b/doc/index-files/index-3.html
@@ -0,0 +1,147 @@
+
+
+
+
+
+D-Index
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A C D E F G H I K L M O P Q R S T U
+
+
+
D
+
+draw(Graphics2D) - Method in class org.jointheleague.graphical.robot.curves.Cubic
+
+draw(Graphics2D) - Method in interface org.jointheleague.graphical.robot.curves.Drawable
+
+Draws the drawable given a graphics context
+
+draw(Graphics2D) - Method in class org.jointheleague.graphical.robot.curves.DynamicPath
+
+draw(Graphics2D) - Method in class org.jointheleague.graphical.robot.curves.Line
+
+draw(Graphics2D) - Method in class org.jointheleague.graphical.robot.curves.Quad
+
+Drawable - Interface in org.jointheleague.graphical.robot.curves
+
+DynamicPath - Class in org.jointheleague.graphical.robot.curves
+
+A Path that is followed by a Robot.
+
+DynamicPath(PathIterator, int, Color, Robot) - Constructor for class org.jointheleague.graphical.robot.curves.DynamicPath
+
+Constructor
+
+
+
A C D E F G H I K L M O P Q R S T U
+
+
+
+
+
+
diff --git a/doc/index-files/index-4.html b/doc/index-files/index-4.html
new file mode 100644
index 0000000..b974431
--- /dev/null
+++ b/doc/index-files/index-4.html
@@ -0,0 +1,131 @@
+
+
+
+
+
+E-Index
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A C D E F G H I K L M O P Q R S T U
+
+
+
E
+
+expand() - Method in class org.jointheleague.graphical.robot.Robot
+
+expand() - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Makes the image of the Robot big
+
+
+
A C D E F G H I K L M O P Q R S T U
+
+
+
+
+
+
diff --git a/doc/index-files/index-5.html b/doc/index-files/index-5.html
new file mode 100644
index 0000000..2c0903b
--- /dev/null
+++ b/doc/index-files/index-5.html
@@ -0,0 +1,131 @@
+
+
+
+
+
+F-Index
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A C D E F G H I K L M O P Q R S T U
+
+
+
F
+
+followPath(PathIterator) - Method in class org.jointheleague.graphical.robot.Robot
+
+followPath(PathIterator) - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Move the robot along a path.
+
+
+
A C D E F G H I K L M O P Q R S T U
+
+
+
+
+
+
diff --git a/doc/index-files/index-6.html b/doc/index-files/index-6.html
new file mode 100644
index 0000000..a0e0021
--- /dev/null
+++ b/doc/index-files/index-6.html
@@ -0,0 +1,224 @@
+
+
+
+
+
+G-Index
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A C D E F G H I K L M O P Q R S T U
+
+
+
G
+
+getAngle(float) - Method in class org.jointheleague.graphical.robot.curves.Close
+
+getAngle(float) - Method in class org.jointheleague.graphical.robot.curves.Cubic
+
+getAngle(float) - Method in class org.jointheleague.graphical.robot.curves.Line
+
+getAngle(float) - Method in class org.jointheleague.graphical.robot.curves.Move
+
+getAngle(float) - Method in class org.jointheleague.graphical.robot.curves.Quad
+
+getAngle(float) - Method in interface org.jointheleague.graphical.robot.curves.Segment
+
+Gets the angle of the segment in radians at the position specified by time
+
+getAngle() - Method in class org.jointheleague.graphical.robot.Robot
+
+getAngle() - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Gets the robot's angle of orientation in degrees.
+
+getAngleToTurn(double) - Method in class org.jointheleague.graphical.robot.Robot
+
+getEndAngle() - Method in class org.jointheleague.graphical.robot.curves.Close
+
+getEndAngle() - Method in class org.jointheleague.graphical.robot.curves.Cubic
+
+getEndAngle() - Method in class org.jointheleague.graphical.robot.curves.Line
+
+getEndAngle() - Method in class org.jointheleague.graphical.robot.curves.Move
+
+getEndAngle() - Method in class org.jointheleague.graphical.robot.curves.Quad
+
+getEndAngle() - Method in interface org.jointheleague.graphical.robot.curves.Segment
+
+getInstance() - Static method in class org.jointheleague.graphical.robot.RobotWindow
+
+Returns the single instance of the RobotWindow
+
+getPenColor() - Method in class org.jointheleague.graphical.robot.Robot
+
+getPenColor() - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+getPenWidth() - Method in class org.jointheleague.graphical.robot.Robot
+
+getPenWidth() - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+getPos(float) - Method in class org.jointheleague.graphical.robot.curves.Close
+
+getPos(float) - Method in class org.jointheleague.graphical.robot.curves.Cubic
+
+getPos(float) - Method in class org.jointheleague.graphical.robot.curves.Line
+
+getPos(float) - Method in class org.jointheleague.graphical.robot.curves.Move
+
+getPos(float) - Method in class org.jointheleague.graphical.robot.curves.Quad
+
+getPos(float) - Method in interface org.jointheleague.graphical.robot.curves.Segment
+
+Return the position on the segment at time t.
+
+getSize() - Method in class org.jointheleague.graphical.robot.curves.Close
+
+getSize() - Method in class org.jointheleague.graphical.robot.curves.Cubic
+
+getSize() - Method in class org.jointheleague.graphical.robot.curves.Line
+
+getSize() - Method in class org.jointheleague.graphical.robot.curves.Move
+
+getSize() - Method in class org.jointheleague.graphical.robot.curves.Quad
+
+getSize() - Method in interface org.jointheleague.graphical.robot.curves.Segment
+
+The time a robot uses to trace a segment at a given speed is
+ proportional to the segment's size.
+
+getStartAngle() - Method in class org.jointheleague.graphical.robot.curves.Close
+
+getStartAngle() - Method in class org.jointheleague.graphical.robot.curves.Cubic
+
+getStartAngle() - Method in class org.jointheleague.graphical.robot.curves.Line
+
+getStartAngle() - Method in class org.jointheleague.graphical.robot.curves.Move
+
+getStartAngle() - Method in class org.jointheleague.graphical.robot.curves.Quad
+
+getStartAngle() - Method in interface org.jointheleague.graphical.robot.curves.Segment
+
+getX() - Method in class org.jointheleague.graphical.robot.Robot
+
+getX() - Method in class org.jointheleague.graphical.robot.Robot.Pos
+
+getX() - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+getY() - Method in class org.jointheleague.graphical.robot.Robot
+
+getY() - Method in class org.jointheleague.graphical.robot.Robot.Pos
+
+getY() - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+
+
A C D E F G H I K L M O P Q R S T U
+
+
+
+
+
+
diff --git a/doc/index-files/index-7.html b/doc/index-files/index-7.html
new file mode 100644
index 0000000..b246cae
--- /dev/null
+++ b/doc/index-files/index-7.html
@@ -0,0 +1,131 @@
+
+
+
+
+
+H-Index
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A C D E F G H I K L M O P Q R S T U
+
+
+
H
+
+hide() - Method in class org.jointheleague.graphical.robot.Robot
+
+hide() - Method in interface org.jointheleague.graphical.robot.RobotInterface
+
+Make the Robot invisible.
+
+
+
A C D E F G H I K L M O P Q R S T U
+
+
+
+
+
+
diff --git a/doc/index-files/index-8.html b/doc/index-files/index-8.html
new file mode 100644
index 0000000..0d64309
--- /dev/null
+++ b/doc/index-files/index-8.html
@@ -0,0 +1,132 @@
+
+
+
+
+
+I-Index
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A C D E F G H I K L M O P Q R S T U
+
+
+
I
+
+incrementTime(double) - Method in class org.jointheleague.graphical.robot.curves.DynamicPath
+
+Moves the robot forward on the path by an increment that
+ is proportional to the speed.
+
+isComplete() - Method in class org.jointheleague.graphical.robot.curves.DynamicPath
+
+
+
A C D E F G H I K L M O P Q R S T U
+
+
+
+
+
+
diff --git a/doc/index-files/index-9.html b/doc/index-files/index-9.html
new file mode 100644
index 0000000..aaa04e1
--- /dev/null
+++ b/doc/index-files/index-9.html
@@ -0,0 +1,149 @@
+
+
+
+
+
+K-Index
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A C D E F G H I K L M O P Q R S T U
+
+
+
K
+
+KeyboardAdapter - Class in org.jointheleague.graphical.robot
+
+
+ This class is used to control a robot through key presses.
+
+KeyboardAdapter() - Constructor for class org.jointheleague.graphical.robot.KeyboardAdapter
+
+Constructor.
+
+keyPressed(KeyEvent) - Method in class org.jointheleague.graphical.robot.KeyboardAdapter
+
+Implements the natural movements associated with the up, down, left, and
+ right arrow keys.
+
+keyReleased(KeyEvent) - Method in class org.jointheleague.graphical.robot.KeyboardAdapter
+
+Implements the natural movements associated with the up, down, left, and
+ right arrow keys.
+
+keyTyped(KeyEvent) - Method in class org.jointheleague.graphical.robot.KeyboardAdapter
+
+No actions are specified, but that can be overridden in extensions of
+ this class.
+
+
+
A C D E F G H I K L M O P Q R S T U
+
+
+
+
+
+
diff --git a/doc/index.html b/doc/index.html
new file mode 100644
index 0000000..2f46fc1
--- /dev/null
+++ b/doc/index.html
@@ -0,0 +1,75 @@
+
+
+
+
+
+Generated Documentation (Untitled)
+
+
+
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+Frame Alert
+This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to Non-frame version .
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/Drawable.html b/doc/org/jointheleague/graphical/robot/Drawable.html
new file mode 100644
index 0000000..6cb8418
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/Drawable.html
@@ -0,0 +1,230 @@
+
+
+
+
+
+Drawable
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
+Summary:
+Nested |
+Field |
+Constr |
+Method
+
+
+Detail:
+Field |
+Constr |
+Method
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Method Summary
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Method Detail
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Summary:
+Nested |
+Field |
+Constr |
+Method
+
+
+Detail:
+Field |
+Constr |
+Method
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/KeyboardAdapter.html b/doc/org/jointheleague/graphical/robot/KeyboardAdapter.html
new file mode 100644
index 0000000..1afaab9
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/KeyboardAdapter.html
@@ -0,0 +1,520 @@
+
+
+
+
+
+KeyboardAdapter
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+Field Summary
+
+Fields
+
+Modifier and Type
+Field and Description
+
+
+protected Robot
+robot
+The Robot instance that the KeyboardAdapter is attached to.
+
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+KeyboardAdapter ()
+Constructor.
+
+
+
+
+
+
+
+
+
+
+Method Summary
+
+All Methods Instance Methods Concrete Methods
+
+Modifier and Type
+Method and Description
+
+
+void
+keyPressed (java.awt.event.KeyEvent e)
+Implements the natural movements associated with the up, down, left, and
+ right arrow keys.
+
+
+
+void
+keyReleased (java.awt.event.KeyEvent e)
+Implements the natural movements associated with the up, down, left, and
+ right arrow keys.
+
+
+
+void
+keyTyped (java.awt.event.KeyEvent e)
+No actions are specified, but that can be overridden in extensions of
+ this class.
+
+
+
+void
+run ()
+
+
+protected void
+setMovingBackward (boolean movingBackward)
+Sets or unsets the Robot in a backward motion.
+
+
+
+protected void
+setMovingForward (boolean movingForward)
+Sets or unsets the Robot in a forward motion.
+
+
+
+void
+setRobot (Robot robot)
+
+
+protected void
+setTurningLeft (boolean turningLeft)
+Sets or unsets the Robot in a left turning motion.
+
+
+
+protected void
+setTurningRight (boolean turningRight)
+Sets or unsets the Robot in a left turning motion.
+
+
+
+
+
+
+
+Methods inherited from class java.lang.Object
+clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Field Detail
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+KeyboardAdapter
+public KeyboardAdapter()
+Constructor.
+
+
+
+
+
+
+
+
+
+Method Detail
+
+
+
+
+
+
+
+
+
+run
+public void run()
+
+Specified by:
+run in interface java.lang.Runnable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+keyTyped
+public void keyTyped(java.awt.event.KeyEvent e)
+No actions are specified, but that can be overridden in extensions of
+ this class.
+
+Specified by:
+keyTyped in interface java.awt.event.KeyListener
+
+
+
+
+
+
+
+
+keyPressed
+public void keyPressed(java.awt.event.KeyEvent e)
+Implements the natural movements associated with the up, down, left, and
+ right arrow keys.
+
+Specified by:
+keyPressed in interface java.awt.event.KeyListener
+
+
+
+
+
+
+
+
+keyReleased
+public void keyReleased(java.awt.event.KeyEvent e)
+Implements the natural movements associated with the up, down, left, and
+ right arrow keys.
+
+Specified by:
+keyReleased in interface java.awt.event.KeyListener
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/Line.html b/doc/org/jointheleague/graphical/robot/Line.html
new file mode 100644
index 0000000..7366841
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/Line.html
@@ -0,0 +1,278 @@
+
+
+
+
+
+Line
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+org.jointheleague.graphical.robot.Line
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+Line (int startX,
+ int startY,
+ int endX,
+ int endY,
+ int lineSize,
+ java.awt.Color color)
+
+
+
+
+
+
+
+
+
+Method Summary
+
+
+
+
+
+Methods inherited from class java.lang.Object
+clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+Line
+public Line(int startX,
+ int startY,
+ int endX,
+ int endY,
+ int lineSize,
+ java.awt.Color color)
+
+
+
+
+
+
+
+
+
+Method Detail
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/Robot.Pos.html b/doc/org/jointheleague/graphical/robot/Robot.Pos.html
new file mode 100644
index 0000000..7ba495e
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/Robot.Pos.html
@@ -0,0 +1,288 @@
+
+
+
+
+
+Robot.Pos
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+Pos (float x,
+ float y)
+
+
+
+
+
+
+
+
+
+Method Summary
+
+
+
+
+
+Methods inherited from class java.lang.Object
+clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+
+
+
+
+
+
+Method Detail
+
+
+
+
+
+getX
+public float getX()
+
+
+
+
+
+
+
+getY
+public float getY()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/Robot.html b/doc/org/jointheleague/graphical/robot/Robot.html
new file mode 100644
index 0000000..238537a
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/Robot.html
@@ -0,0 +1,1381 @@
+
+
+
+
+
+Robot
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+Nested Class Summary
+
+Nested Classes
+
+Modifier and Type
+Class and Description
+
+
+static class
+Robot.Pos
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+Robot ()
+
+
+Robot (java.awt.image.BufferedImage robotImage)
+Instantiates a new Robot at the center of the RobotWindow.
+
+
+
+Robot (java.awt.image.BufferedImage inputImage,
+ int xPos,
+ int yPos)
+
+
+Robot (int xPos,
+ int yPos)
+Instantiates a new default Robot at the position provided.
+
+
+
+Robot (java.lang.String fileName)
+Instantiates a new Robot whose image is specified by the filename at the
+ center of the RobotWindow.
+
+
+
+Robot (java.lang.String fileName,
+ int xPos,
+ int yPos)
+
+
+
+
+
+
+
+
+
+Method Summary
+
+All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods
+
+Modifier and Type
+Method and Description
+
+
+void
+addKeyboardAdapter (KeyboardAdapter adapter)
+
+
+
+
+void
+changeRobot (java.awt.image.BufferedImage im)
+Changes the image of the Robot
+
+
+
+void
+changeRobot (java.lang.String urlName)
+Changes the image of the Robot
+
+
+
+void
+clearDrawables ()
+Removes all lines drawn by this Robot.
+
+
+
+void
+cubicTo (float x1,
+ float y1,
+ float x2,
+ float y2,
+ float x3,
+ float y3,
+ boolean relative)
+Move the robot along a cubic curve given by the robot's current position
+ and the control points (x1, y1), (x2, y2) and (x3, y3).
+
+
+
+void
+expand ()
+Makes the image of the Robot big
+
+
+
+void
+followPath (java.awt.geom.PathIterator pathIterator)
+Move the robot along a path.
+
+
+
+double
+getAngle ()
+Gets the robot's angle of orientation in degrees.
+
+
+
+double
+getAngleToTurn (double targetAngle)
+
+
+java.awt.Color
+getPenColor ()
+
+
+int
+getPenWidth ()
+
+
+float
+getX ()
+
+
+float
+getY ()
+
+
+void
+hide ()
+Make the Robot invisible.
+
+
+
+void
+lineTo (float x,
+ float y,
+ boolean relative)
+Move the robot forward to a given position.
+
+
+
+void
+microMove (int sgn)
+Makes the Robot move one step.
+
+
+
+void
+microTurn (int sgn)
+Makes the Robot turn in place a small angle.
+
+
+
+void
+miniaturize ()
+Makes the image of the Robot small
+
+
+
+void
+move (int distance)
+Makes the robot move a given distance.
+
+
+
+void
+moveTo (float x,
+ float y)
+Deprecated.
+
+
+
+void
+moveTo (float x,
+ float y,
+ boolean relative,
+ boolean jump)
+Move the Robot to a given position.
+
+
+
+void
+penDown ()
+Set the pen down, i.e., the Robot traces its movements with lines or curves.
+
+
+
+void
+penUp ()
+Lifts the pen, i.e., the Robot stops drawing lines or curves.
+
+
+
+void
+quadTo (float x1,
+ float y1,
+ float x2,
+ float y2,
+ boolean relative)
+Move the robot along a quadratic curve given by the robot's current position
+ and the control points (x1, y1) and (x2, y2).
+
+
+
+void
+setAngle (double a)
+Set the robot's angle of orientation.
+
+
+
+void
+setPenColor (java.awt.Color color)
+Sets the pen color
+
+
+
+void
+setPenColor (int r,
+ int g,
+ int b)
+Sets the pen color given the red, green and blue components of the new
+ color.
+
+
+
+void
+setPenWidth (int size)
+Sets the pen size.
+
+
+
+void
+setPos (float x,
+ float y)
+Set the position of the robot to (x, y) while maintaining its direction.
+
+
+
+void
+setRandomPenColor ()
+Sets the pen color to a random color.
+
+
+
+void
+setSpeed (int speed)
+Sets the speed of the Robot.
+
+
+
+static void
+setWindowColor (java.awt.Color color)
+Sets the window's background color
+
+
+
+static void
+setWindowColor (int r,
+ int g,
+ int b)
+Sets the window's background color given the red, green and blue
+ components of the new color.
+
+
+
+static void
+setWindowImage (java.lang.String imageLocation)
+Sets the window's background image
+
+
+
+static void
+setWindowSize (int width,
+ int height)
+Sets the window size
+
+
+
+void
+show ()
+Makes the Robot visible
+
+
+
+void
+sleep (int millis)
+Waits a given number of milliseconds.
+
+
+
+void
+sparkle ()
+Makes the Robot sparkle.
+
+
+
+void
+turn (double degrees)
+Makes the Robot turn in place a given number of degrees.
+
+
+
+void
+unSparkle ()
+Removes sparkles
+
+
+
+
+
+
+
+Methods inherited from class java.lang.Object
+clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+Robot
+public Robot()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Method Detail
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+setWindowColor
+public static void setWindowColor(int r,
+ int g,
+ int b)
+Sets the window's background color given the red, green and blue
+ components of the new color. The components are specified as an integer
+ between 0 and 255.
+
+Parameters:
+r - the red component of the new color
+g - the green component of the new color
+b - the blue component of the new color
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+setPenColor
+public void setPenColor(int r,
+ int g,
+ int b)
+
+Sets the pen color given the red, green and blue components of the new
+ color. The components are specified as an integer between 0 and 255.
+
+Specified by:
+setPenColor in interface RobotInterface
+Parameters:
+r - the red component of the new color
+g - the green component of the new color
+b - the blue component of the new color
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+setPos
+public void setPos(float x,
+ float y)
+
+Set the position of the robot to (x, y) while maintaining its direction.
+
+Specified by:
+setPos in interface RobotInterface
+Parameters:
+x - the x-coordinate of the new position
+y - the y-coordinate of the new position
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+sparkle
+public void sparkle()
+
+Makes the Robot sparkle.
+
+Specified by:
+sparkle in interface RobotInterface
+
+
+
+
+
+
+
+
+unSparkle
+public void unSparkle()
+
+Removes sparkles
+
+Specified by:
+unSparkle in interface RobotInterface
+
+
+
+
+
+
+
+
+
+
+
+
+show
+public void show()
+
+Makes the Robot visible
+
+Specified by:
+show in interface RobotInterface
+
+
+
+
+
+
+
+
+
+
+
+
+microMove
+public void microMove(int sgn)
+ throws java.lang.InterruptedException
+
+Makes the Robot move one step. If the sgn is negative, the Robot moves
+ one step backwards. The step size depends on the Robot's speed. This
+ method is intended to be used by a KeyboardAdapter.
+
+Specified by:
+microMove in interface RobotInterface
+Parameters:
+sgn - if positive the Robot moves forward, if negative the Robot
+ moves backwards.
+Throws:
+java.lang.InterruptedException - if interrupted before making the turn (which is very unlikely
+ to happen).
+
+
+
+
+
+
+
+
+turn
+public void turn(double degrees)
+
+Makes the Robot turn in place a given number of degrees. If the argument
+ is positive, the Robot turn clockwise, if negative the Robot turns
+ counter-clockwise.
+
+Specified by:
+turn in interface RobotInterface
+Parameters:
+degrees - The number of degrees to turn.
+
+
+
+
+
+
+
+
+microTurn
+public void microTurn(int sgn)
+ throws java.lang.InterruptedException
+
+Makes the Robot turn in place a small angle. If the argument is positive,
+ the Robot turn clockwise, if negative the Robot turns counter-clockwise.
+ The angle turn is dependent on the Robot's speed.
+
+Specified by:
+microTurn in interface RobotInterface
+Parameters:
+sgn - The sign of the direction to turn.
+Throws:
+java.lang.InterruptedException - if interrupted before making the turn (which is very unlikely
+ to happen).
+
+
+
+
+
+
+
+
+
+
+
+
+moveTo
+@Deprecated
+public void moveTo(float x,
+ float y)
+Deprecated.
+
+Places the robot at (x, y)
+
+Specified by:
+moveTo in interface RobotInterface
+Parameters:
+x - the x-coordinate
+y - the y-coordinate
+
+
+
+
+
+
+
+
+moveTo
+public void moveTo(float x,
+ float y,
+ boolean relative,
+ boolean jump)
+
+Move the Robot to a given position. The Robot does not draw any line
+ regardless of whether pen is up or down. Unless jump is true,
+ if necessary, turn the robot first such that it is heading in the right
+ direction before moving the robot.
+
+Specified by:
+moveTo in interface RobotInterface
+Parameters:
+x - the x-coordinate of the new position
+y - the y-coordinate of the new position
+relative - if true, x and y a relative to the robot's current position
+jump - if true, place robot directly at the new position. Otherwise,
+ move the robot to the new position at the speed of the robot.
+
+
+
+
+
+
+
+
+lineTo
+public void lineTo(float x,
+ float y,
+ boolean relative)
+
+Move the robot forward to a given position. If necessary, turn the robot
+ first such that it is heading in the right direction.
+
+Specified by:
+lineTo in interface RobotInterface
+Parameters:
+x - the x-coordinate of the robot's destination
+y - the y-coordinate of the robot's destination
+relative - if true, x and y are given relative to the robot's current
+ position
+
+
+
+
+
+
+
+
+quadTo
+public void quadTo(float x1,
+ float y1,
+ float x2,
+ float y2,
+ boolean relative)
+
+Move the robot along a quadratic curve given by the robot's current position
+ and the control points (x1, y1) and (x2, y2). If necessary, turn the robot
+ first such that it is heading in the right direction.
+
+Specified by:
+quadTo in interface RobotInterface
+Parameters:
+x1 - the x-coordinate of the first control point
+y1 - the y-coordinate of the first control point
+x2 - the x-coordinate of the second control point
+y2 - the y-coordinate of the second control point
+relative - if true, the coordinates are give relative to the robot's
+ current position
+
+
+
+
+
+
+
+
+cubicTo
+public void cubicTo(float x1,
+ float y1,
+ float x2,
+ float y2,
+ float x3,
+ float y3,
+ boolean relative)
+
+Move the robot along a cubic curve given by the robot's current position
+ and the control points (x1, y1), (x2, y2) and (x3, y3). If necessary, turn
+ the robot first such that it is heading in the right direction.
+
+Specified by:
+cubicTo in interface RobotInterface
+Parameters:
+x1 - the x-coordinate of the first control point
+y1 - the y-coordinate of the first control point
+x2 - the x-coordinate of the second control point
+y2 - the y-coordinate of the second control point
+x3 - the x-coordinate of the third control point
+y3 - the y-coordinate of the third control point
+relative - if true, the coordinates are give relative to the robot's
+ current position
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+getX
+public float getX()
+
+Specified by:
+getX in interface RobotInterface
+Returns:
+the x-coordinate of the robot's position
+
+
+
+
+
+
+
+
+getY
+public float getY()
+
+Specified by:
+getY in interface RobotInterface
+Returns:
+the y-coordinate of the robot's position
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/RobotImage.html b/doc/org/jointheleague/graphical/robot/RobotImage.html
new file mode 100644
index 0000000..23920b4
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/RobotImage.html
@@ -0,0 +1,296 @@
+
+
+
+
+
+RobotImage
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+RobotImage ()
+
+
+
+
+
+
+
+
+
+Method Summary
+
+
+
+
+
+Methods inherited from class java.lang.Object
+clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+RobotImage
+public RobotImage()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/RobotInterface.html b/doc/org/jointheleague/graphical/robot/RobotInterface.html
new file mode 100644
index 0000000..0e6554a
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/RobotInterface.html
@@ -0,0 +1,956 @@
+
+
+
+
+
+RobotInterface
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
+Summary:
+Nested |
+Field |
+Constr |
+Method
+
+
+Detail:
+Field |
+Constr |
+Method
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Method Summary
+
+All Methods Instance Methods Abstract Methods Deprecated Methods
+
+Modifier and Type
+Method and Description
+
+
+void
+addKeyboardAdapter (KeyboardAdapter adapter)
+
+
+
+
+void
+changeRobot (java.awt.image.BufferedImage im)
+Changes the image of the Robot
+
+
+
+void
+changeRobot (java.lang.String urlName)
+Changes the image of the Robot
+
+
+
+void
+clearDrawables ()
+Removes all lines drawn by this Robot.
+
+
+
+void
+cubicTo (float x1,
+ float y1,
+ float x2,
+ float y2,
+ float x3,
+ float y3,
+ boolean relative)
+Move the robot along a cubic curve given by the robot's current position
+ and the control points (x1, y1), (x2, y2) and (x3, y3).
+
+
+
+void
+expand ()
+Makes the image of the Robot big
+
+
+
+void
+followPath (java.awt.geom.PathIterator pathIterator)
+Move the robot along a path.
+
+
+
+double
+getAngle ()
+Gets the robot's angle of orientation in degrees.
+
+
+
+java.awt.Color
+getPenColor ()
+
+
+int
+getPenWidth ()
+
+
+float
+getX ()
+
+
+float
+getY ()
+
+
+void
+hide ()
+Make the Robot invisible.
+
+
+
+void
+lineTo (float x,
+ float y,
+ boolean relative)
+Move the robot forward to a given position.
+
+
+
+void
+microMove (int sgn)
+Makes the Robot move one step.
+
+
+
+void
+microTurn (int sgn)
+Makes the Robot turn in place a small angle.
+
+
+
+void
+miniaturize ()
+Makes the image of the Robot small
+
+
+
+void
+move (int distance)
+Makes the robot move a given distance.
+
+
+
+void
+moveTo (float x,
+ float y)
+
+
+
+
+void
+moveTo (float x,
+ float y,
+ boolean relative,
+ boolean jump)
+Move the Robot to a given position.
+
+
+
+void
+penDown ()
+Set the pen down, i.e., the Robot traces its movements with lines or curves.
+
+
+
+void
+penUp ()
+Lifts the pen, i.e., the Robot stops drawing lines or curves.
+
+
+
+void
+quadTo (float x1,
+ float y1,
+ float x2,
+ float y2,
+ boolean relative)
+Move the robot along a quadratic curve given by the robot's current position
+ and the control points (x1, y1) and (x2, y2).
+
+
+
+void
+setAngle (double a)
+Set the robot's angle of orientation.
+
+
+
+void
+setPenColor (java.awt.Color color)
+Sets the pen color
+
+
+
+void
+setPenColor (int r,
+ int g,
+ int b)
+Sets the pen color given the red, green and blue components of the new
+ color.
+
+
+
+void
+setPenWidth (int size)
+Sets the pen size.
+
+
+
+void
+setPos (float x,
+ float y)
+Set the position of the robot to (x, y) while maintaining its direction.
+
+
+
+void
+setRandomPenColor ()
+Sets the pen color to a random color.
+
+
+
+void
+setSpeed (int speed)
+Sets the speed of the Robot.
+
+
+
+void
+show ()
+Makes the Robot visible
+
+
+
+void
+sleep (int millis)
+Waits a given number of milliseconds.
+
+
+
+void
+sparkle ()
+Makes the Robot sparkle.
+
+
+
+void
+turn (double degrees)
+Makes the Robot turn in place a given number of degrees.
+
+
+
+void
+unSparkle ()
+Removes sparkles
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Method Detail
+
+
+
+
+
+
+
+
+
+
+
+
+
+getPenWidth
+int getPenWidth()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+setPenColor
+void setPenColor(int r,
+ int g,
+ int b)
+Sets the pen color given the red, green and blue components of the new
+ color. The components are specified as an integer between 0 and 255.
+
+Parameters:
+r - the red component of the new color
+g - the green component of the new color
+b - the blue component of the new color
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+setPos
+void setPos(float x,
+ float y)
+Set the position of the robot to (x, y) while maintaining its direction.
+
+Parameters:
+x - the x-coordinate of the new position
+y - the y-coordinate of the new position
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+sparkle
+void sparkle()
+Makes the Robot sparkle.
+
+
+
+
+
+
+
+unSparkle
+void unSparkle()
+Removes sparkles
+
+
+
+
+
+
+
+
+
+
+
+show
+void show()
+Makes the Robot visible
+
+
+
+
+
+
+
+
+
+
+
+microMove
+void microMove(int sgn)
+ throws java.lang.InterruptedException
+Makes the Robot move one step. If the sgn is negative, the Robot moves
+ one step backwards. The step size depends on the Robot's speed. This
+ method is intended to be used by a KeyboardAdapter.
+
+Parameters:
+sgn - if positive the Robot moves forward, if negative the Robot
+ moves backwards.
+Throws:
+java.lang.InterruptedException - if interrupted before making the turn (which is very unlikely
+ to happen).
+java.lang.IllegalArgumentException - if sgn is 0.
+
+
+
+
+
+
+
+
+turn
+void turn(double degrees)
+Makes the Robot turn in place a given number of degrees. If the argument
+ is positive, the Robot turn clockwise, if negative the Robot turns
+ counter-clockwise.
+
+Parameters:
+degrees - The number of degrees to turn.
+
+
+
+
+
+
+
+
+microTurn
+void microTurn(int sgn)
+ throws java.lang.InterruptedException
+Makes the Robot turn in place a small angle. If the argument is positive,
+ the Robot turn clockwise, if negative the Robot turns counter-clockwise.
+ The angle turn is dependent on the Robot's speed.
+
+Parameters:
+sgn - The sign of the direction to turn.
+Throws:
+java.lang.InterruptedException - if interrupted before making the turn (which is very unlikely
+ to happen).
+java.lang.IllegalArgumentException - if the sgn is 0.
+
+
+
+
+
+
+
+
+
+
+
+
+moveTo
+@Deprecated
+void moveTo(float x,
+ float y)
+Deprecated.
+Places the robot at (x, y)
+
+Parameters:
+x - the x-coordinate
+y - the y-coordinate
+
+
+
+
+
+
+
+
+moveTo
+void moveTo(float x,
+ float y,
+ boolean relative,
+ boolean jump)
+Move the Robot to a given position. The Robot does not draw any line
+ regardless of whether pen is up or down. Unless jump is true,
+ if necessary, turn the robot first such that it is heading in the right
+ direction before moving the robot.
+
+Parameters:
+x - the x-coordinate of the new position
+y - the y-coordinate of the new position
+relative - if true, x and y a relative to the robot's current position
+jump - if true, place robot directly at the new position. Otherwise,
+ move the robot to the new position at the speed of the robot.
+
+
+
+
+
+
+
+
+lineTo
+void lineTo(float x,
+ float y,
+ boolean relative)
+Move the robot forward to a given position. If necessary, turn the robot
+ first such that it is heading in the right direction.
+
+Parameters:
+x - the x-coordinate of the robot's destination
+y - the y-coordinate of the robot's destination
+relative - if true, x and y are given relative to the robot's current
+ position
+
+
+
+
+
+
+
+
+quadTo
+void quadTo(float x1,
+ float y1,
+ float x2,
+ float y2,
+ boolean relative)
+Move the robot along a quadratic curve given by the robot's current position
+ and the control points (x1, y1) and (x2, y2). If necessary, turn the robot
+ first such that it is heading in the right direction.
+
+Parameters:
+x1 - the x-coordinate of the first control point
+y1 - the y-coordinate of the first control point
+x2 - the x-coordinate of the second control point
+y2 - the y-coordinate of the second control point
+relative - if true, the coordinates are give relative to the robot's
+ current position
+
+
+
+
+
+
+
+
+cubicTo
+void cubicTo(float x1,
+ float y1,
+ float x2,
+ float y2,
+ float x3,
+ float y3,
+ boolean relative)
+Move the robot along a cubic curve given by the robot's current position
+ and the control points (x1, y1), (x2, y2) and (x3, y3). If necessary, turn
+ the robot first such that it is heading in the right direction.
+
+Parameters:
+x1 - the x-coordinate of the first control point
+y1 - the y-coordinate of the first control point
+x2 - the x-coordinate of the second control point
+y2 - the y-coordinate of the second control point
+x3 - the x-coordinate of the third control point
+y3 - the y-coordinate of the third control point
+relative - if true, the coordinates are give relative to the robot's
+ current position
+
+
+
+
+
+
+
+
+
+
+
+
+getX
+float getX()
+
+Returns:
+the x-coordinate of the robot's position
+
+
+
+
+
+
+
+
+getY
+float getY()
+
+Returns:
+the y-coordinate of the robot's position
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Summary:
+Nested |
+Field |
+Constr |
+Method
+
+
+Detail:
+Field |
+Constr |
+Method
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/RobotWindow.html b/doc/org/jointheleague/graphical/robot/RobotWindow.html
new file mode 100644
index 0000000..effed29
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/RobotWindow.html
@@ -0,0 +1,444 @@
+
+
+
+
+
+RobotWindow
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Detail:
+Field |
+Constr |
+Method
+
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+java.awt.Component
+
+
+java.awt.Container
+
+
+javax.swing.JComponent
+
+
+javax.swing.JPanel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Nested Class Summary
+
+
+
+
+Nested classes/interfaces inherited from class javax.swing.JPanel
+javax.swing.JPanel.AccessibleJPanel
+
+
+
+
+
+Nested classes/interfaces inherited from class javax.swing.JComponent
+javax.swing.JComponent.AccessibleJComponent
+
+
+
+
+
+Nested classes/interfaces inherited from class java.awt.Container
+java.awt.Container.AccessibleAWTContainer
+
+
+
+
+
+Nested classes/interfaces inherited from class java.awt.Component
+java.awt.Component.AccessibleAWTComponent, java.awt.Component.BaselineResizeBehavior, java.awt.Component.BltBufferStrategy, java.awt.Component.FlipBufferStrategy
+
+
+
+
+
+
+
+
+Field Summary
+
+
+
+
+Fields inherited from class javax.swing.JComponent
+listenerList, TOOL_TIP_TEXT_KEY, ui, UNDEFINED_CONDITION, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, WHEN_FOCUSED, WHEN_IN_FOCUSED_WINDOW
+
+
+
+
+
+Fields inherited from class java.awt.Component
+accessibleContext, BOTTOM_ALIGNMENT, CENTER_ALIGNMENT, LEFT_ALIGNMENT, RIGHT_ALIGNMENT, TOP_ALIGNMENT
+
+
+
+
+
+Fields inherited from interface java.awt.image.ImageObserver
+ABORT, ALLBITS, ERROR, FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, WIDTH
+
+
+
+
+
+
+
+
+Method Summary
+
+
+
+
+
+Methods inherited from class javax.swing.JPanel
+getAccessibleContext, getUI, getUIClassID, paramString, setUI, updateUI
+
+
+
+
+
+Methods inherited from class javax.swing.JComponent
+addAncestorListener, addNotify, addVetoableChangeListener, computeVisibleRect, contains, createToolTip, disable, enable, firePropertyChange, firePropertyChange, firePropertyChange, fireVetoableChange, getActionForKeyStroke, getActionMap, getAlignmentX, getAlignmentY, getAncestorListeners, getAutoscrolls, getBaseline, getBaselineResizeBehavior, getBorder, getBounds, getClientProperty, getComponentGraphics, getComponentPopupMenu, getConditionForKeyStroke, getDebugGraphicsOptions, getDefaultLocale, getFontMetrics, getGraphics, getHeight, getInheritsPopupMenu, getInputMap, getInputMap, getInputVerifier, getInsets, getInsets, getListeners, getLocation, getMaximumSize, getMinimumSize, getNextFocusableComponent, getPopupLocation, getPreferredSize, getRegisteredKeyStrokes, getRootPane, getSize, getToolTipLocation, getToolTipText, getToolTipText, getTopLevelAncestor, getTransferHandler, getVerifyInputWhenFocusTarget, getVetoableChangeListeners, getVisibleRect, getWidth, getX, getY, grabFocus, hide, isDoubleBuffered, isLightweightComponent, isManagingFocus, isOpaque, isOptimizedDrawingEnabled, isPaintingForPrint, isPaintingOrigin, isPaintingTile, isRequestFocusEnabled, isValidateRoot, paint, paintBorder, paintChildren, paintImmediately, paintImmediately, print, printAll, printBorder, printChildren, printComponent, processComponentKeyEvent, processKeyBinding, processKeyEvent, processMouseEvent, processMouseMotionEvent, putClientProperty, registerKeyboardAction, registerKeyboardAction, removeAncestorListener, removeNotify, removeVetoableChangeListener, repaint, repaint, requestDefaultFocus, requestFocus, requestFocus, requestFocusInWindow, requestFocusInWindow, resetKeyboardActions, reshape, revalidate, scrollRectToVisible, setActionMap, setAlignmentX, setAlignmentY, setAutoscrolls, setBackground, setBorder, setComponentPopupMenu, setDebugGraphicsOptions, setDefaultLocale, setDoubleBuffered, setEnabled, setFocusTraversalKeys, setFont, setForeground, setInheritsPopupMenu, setInputMap, setInputVerifier, setMaximumSize, setMinimumSize, setNextFocusableComponent, setOpaque, setPreferredSize, setRequestFocusEnabled, setToolTipText, setTransferHandler, setUI, setVerifyInputWhenFocusTarget, setVisible, unregisterKeyboardAction, update
+
+
+
+
+
+Methods inherited from class java.awt.Container
+add, add, add, add, add, addContainerListener, addImpl, addPropertyChangeListener, addPropertyChangeListener, applyComponentOrientation, areFocusTraversalKeysSet, countComponents, deliverEvent, doLayout, findComponentAt, findComponentAt, getComponent, getComponentAt, getComponentAt, getComponentCount, getComponents, getComponentZOrder, getContainerListeners, getFocusTraversalKeys, getFocusTraversalPolicy, getLayout, getMousePosition, insets, invalidate, isAncestorOf, isFocusCycleRoot, isFocusCycleRoot, isFocusTraversalPolicyProvider, isFocusTraversalPolicySet, layout, list, list, locate, minimumSize, paintComponents, preferredSize, printComponents, processContainerEvent, processEvent, remove, remove, removeAll, removeContainerListener, setComponentZOrder, setFocusCycleRoot, setFocusTraversalPolicy, setFocusTraversalPolicyProvider, setLayout, transferFocusDownCycle, validate, validateTree
+
+
+
+
+
+Methods inherited from class java.awt.Component
+action, add, addComponentListener, addFocusListener, addHierarchyBoundsListener, addHierarchyListener, addInputMethodListener, addKeyListener, addMouseListener, addMouseMotionListener, addMouseWheelListener, bounds, checkImage, checkImage, coalesceEvents, contains, createImage, createImage, createVolatileImage, createVolatileImage, disableEvents, dispatchEvent, enable, enableEvents, enableInputMethods, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, getBackground, getBounds, getColorModel, getComponentListeners, getComponentOrientation, getCursor, getDropTarget, getFocusCycleRootAncestor, getFocusListeners, getFocusTraversalKeysEnabled, getFont, getForeground, getGraphicsConfiguration, getHierarchyBoundsListeners, getHierarchyListeners, getIgnoreRepaint, getInputContext, getInputMethodListeners, getInputMethodRequests, getKeyListeners, getLocale, getLocation, getLocationOnScreen, getMouseListeners, getMouseMotionListeners, getMousePosition, getMouseWheelListeners, getName, getParent, getPeer, getPropertyChangeListeners, getPropertyChangeListeners, getSize, getToolkit, getTreeLock, gotFocus, handleEvent, hasFocus, imageUpdate, inside, isBackgroundSet, isCursorSet, isDisplayable, isEnabled, isFocusable, isFocusOwner, isFocusTraversable, isFontSet, isForegroundSet, isLightweight, isMaximumSizeSet, isMinimumSizeSet, isPreferredSizeSet, isShowing, isValid, isVisible, keyDown, keyUp, list, list, list, location, lostFocus, mouseDown, mouseDrag, mouseEnter, mouseExit, mouseMove, mouseUp, move, nextFocus, paintAll, postEvent, prepareImage, prepareImage, processComponentEvent, processFocusEvent, processHierarchyBoundsEvent, processHierarchyEvent, processInputMethodEvent, processMouseWheelEvent, remove, removeComponentListener, removeFocusListener, removeHierarchyBoundsListener, removeHierarchyListener, removeInputMethodListener, removeKeyListener, removeMouseListener, removeMouseMotionListener, removeMouseWheelListener, removePropertyChangeListener, removePropertyChangeListener, repaint, repaint, repaint, resize, resize, setBounds, setBounds, setComponentOrientation, setCursor, setDropTarget, setFocusable, setFocusTraversalKeysEnabled, setIgnoreRepaint, setLocale, setLocation, setLocation, setName, setSize, setSize, show, show, size, toString, transferFocus, transferFocusBackward, transferFocusUpCycle
+
+
+
+
+
+Methods inherited from class java.lang.Object
+clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Method Detail
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+setWindowSize
+public void setWindowSize(int width,
+ int height)
+Sets the dimension of the panel containing the robots. This method should be invoked on the EDT only.
+
+Parameters:
+width - the width of the panel
+height - the height of the panel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Detail:
+Field |
+Constr |
+Method
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/curves/Close.html b/doc/org/jointheleague/graphical/robot/curves/Close.html
new file mode 100644
index 0000000..6a02cf4
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/curves/Close.html
@@ -0,0 +1,479 @@
+
+
+
+
+
+Close
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+Close (float x,
+ float y,
+ float[] ctrlPoints,
+ int lineSize,
+ java.awt.Color color)
+Constructor
+
+
+
+
+
+
+
+
+
+
+Method Summary
+
+All Methods Instance Methods Concrete Methods
+
+Modifier and Type
+Method and Description
+
+
+java.awt.geom.Path2D
+addTo (java.awt.geom.Path2D path2D)
+Adds the Segment to the end of a Path2D
+
+
+
+java.awt.geom.Path2D
+addTo (java.awt.geom.Path2D path2D,
+ float t)
+Adds a sub-segment of this segment to the end of a Path2D
+
+
+
+double
+getAngle (float t)
+Gets the angle of the segment in radians at the position specified by time
+
+
+
+double
+getEndAngle ()
+
+
+Robot.Pos
+getPos (float t)
+Return the position on the segment at time t.
+
+
+
+float
+getSize ()
+The time a robot uses to trace a segment at a given speed is
+ proportional to the segment's size.
+
+
+
+double
+getStartAngle ()
+
+
+Segment
+subSegment (float t)
+Return the sub-segment of this segment that starts at 0 and ends at t.
+
+
+
+
+
+
+
+Methods inherited from class java.lang.Object
+clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+Close
+public Close(float x,
+ float y,
+ float[] ctrlPoints,
+ int lineSize,
+ java.awt.Color color)
+Constructor
+
+Parameters:
+x - x-coordinate of the segment's starting point
+y - y-coordinate of the segment's starting point
+ctrlPoints - an array of length at least 2 that
+ contains the x- and y-coordinates of the segment's end point.
+lineSize - the line width used to draw the segment
+color - the color used to draw the segment
+
+
+
+
+
+
+
+
+
+
+Method Detail
+
+
+
+
+
+subSegment
+public Segment subSegment(float t)
+Description copied from interface: Segment
+Return the sub-segment of this segment that starts at 0 and ends at t.
+ For t ≤ 0, returns a segment of size 0, and for t ≥ 1F,
+ returns this.
+
+Specified by:
+subSegment in interface Segment
+Parameters:
+t - a float value, normally between 0 and 1
+Returns:
+A sub-segment of this segment
+
+
+
+
+
+
+
+
+getPos
+public Robot.Pos getPos(float t)
+Description copied from interface: Segment
+Return the position on the segment at time t. If t ≤ 0,
+ the start position of this segment is returned, and if t ≥ 1, the end
+ position of this segment is returned.
+
+Specified by:
+getPos in interface Segment
+Parameters:
+t - a float value, normally between 0 and 1
+Returns:
+A position on this segment
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+addTo
+public java.awt.geom.Path2D addTo(java.awt.geom.Path2D path2D,
+ float t)
+Description copied from interface: Segment
+Adds a sub-segment of this segment to the end of a Path2D
+
+Specified by:
+addTo in interface Segment
+Parameters:
+path2D - a Path2D to which the sub-segment is added
+t - a float value, normally between 0 and 1, that
+ specifies the sub-segment of this segment that is added
+Returns:
+a Path2D
+See Also:
+Segment.subSegment(float)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/curves/Cubic.html b/doc/org/jointheleague/graphical/robot/curves/Cubic.html
new file mode 100644
index 0000000..29d5a5c
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/curves/Cubic.html
@@ -0,0 +1,502 @@
+
+
+
+
+
+Cubic
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+Cubic (float x,
+ float y,
+ float[] ctrlPoints,
+ int lineSize,
+ java.awt.Color color)
+Constructor
+
+
+
+
+
+
+
+
+
+
+Method Summary
+
+All Methods Instance Methods Concrete Methods
+
+Modifier and Type
+Method and Description
+
+
+java.awt.geom.Path2D
+addTo (java.awt.geom.Path2D path2D)
+Adds the Segment to the end of a Path2D
+
+
+
+java.awt.geom.Path2D
+addTo (java.awt.geom.Path2D path2D,
+ float t)
+Adds a sub-segment of this segment to the end of a Path2D
+
+
+
+void
+draw (java.awt.Graphics2D g2)
+Draws the drawable given a graphics context
+
+
+
+double
+getAngle (float time)
+Gets the angle of the segment in radians at the position specified by time
+
+
+
+double
+getEndAngle ()
+
+
+Robot.Pos
+getPos (float t)
+Return the position on the segment at time t.
+
+
+
+float
+getSize ()
+The time a robot uses to trace a segment at a given speed is
+ proportional to the segment's size.
+
+
+
+double
+getStartAngle ()
+
+
+Segment
+subSegment (float t)
+Return the sub-segment of this segment that starts at 0 and ends at t.
+
+
+
+
+
+
+
+Methods inherited from class java.lang.Object
+clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+Cubic
+public Cubic(float x,
+ float y,
+ float[] ctrlPoints,
+ int lineSize,
+ java.awt.Color color)
+Constructor
+
+Parameters:
+x - x-coordinate of the segment's starting point
+y - y-coordinate of the segment's starting point
+ctrlPoints - an array of length at least 6 that
+ contains the x- and y-coordinates of the segment's control points.
+lineSize - the line width used to draw the segment
+color - the color used to draw the segment
+
+
+
+
+
+
+
+
+
+
+Method Detail
+
+
+
+
+
+
+
+
+
+subSegment
+public Segment subSegment(float t)
+Description copied from interface: Segment
+Return the sub-segment of this segment that starts at 0 and ends at t.
+ For t ≤ 0, returns a segment of size 0, and for t ≥ 1F,
+ returns this.
+
+Specified by:
+subSegment in interface Segment
+Parameters:
+t - a float value, normally between 0 and 1
+Returns:
+A sub-segment of this segment
+
+
+
+
+
+
+
+
+getPos
+public Robot.Pos getPos(float t)
+Description copied from interface: Segment
+Return the position on the segment at time t. If t ≤ 0,
+ the start position of this segment is returned, and if t ≥ 1, the end
+ position of this segment is returned.
+
+Specified by:
+getPos in interface Segment
+Parameters:
+t - a float value, normally between 0 and 1
+Returns:
+A position on this segment
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+addTo
+public java.awt.geom.Path2D addTo(java.awt.geom.Path2D path2D,
+ float t)
+Description copied from interface: Segment
+Adds a sub-segment of this segment to the end of a Path2D
+
+Specified by:
+addTo in interface Segment
+Parameters:
+path2D - a Path2D to which the sub-segment is added
+t - a float value, normally between 0 and 1, that
+ specifies the sub-segment of this segment that is added
+Returns:
+a Path2D
+See Also:
+Segment.subSegment(float)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/curves/Drawable.html b/doc/org/jointheleague/graphical/robot/curves/Drawable.html
new file mode 100644
index 0000000..629fe29
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/curves/Drawable.html
@@ -0,0 +1,230 @@
+
+
+
+
+
+Drawable
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
+Summary:
+Nested |
+Field |
+Constr |
+Method
+
+
+Detail:
+Field |
+Constr |
+Method
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Method Summary
+
+All Methods Instance Methods Abstract Methods
+
+Modifier and Type
+Method and Description
+
+
+void
+draw (java.awt.Graphics2D g2)
+Draws the drawable given a graphics context
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Method Detail
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Summary:
+Nested |
+Field |
+Constr |
+Method
+
+
+Detail:
+Field |
+Constr |
+Method
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/curves/DynamicPath.html b/doc/org/jointheleague/graphical/robot/curves/DynamicPath.html
new file mode 100644
index 0000000..f8d959a
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/curves/DynamicPath.html
@@ -0,0 +1,341 @@
+
+
+
+
+
+DynamicPath
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+All Implemented Interfaces:
+Drawable
+
+
+
+public final class DynamicPath
+extends java.lang.Object
+implements Drawable
+A Path that is followed by a Robot. Only the part of the path from
+ the path's start to the robot's current position is drawn.
+
+
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+DynamicPath (java.awt.geom.PathIterator pathIterator,
+ int lineSize,
+ java.awt.Color color,
+ Robot robot)
+Constructor
+
+
+
+
+
+
+
+
+
+
+Method Summary
+
+All Methods Instance Methods Concrete Methods
+
+Modifier and Type
+Method and Description
+
+
+void
+draw (java.awt.Graphics2D g2)
+Draws the drawable given a graphics context
+
+
+
+void
+incrementTime (double speed)
+Moves the robot forward on the path by an increment that
+ is proportional to the speed.
+
+
+
+boolean
+isComplete ()
+
+
+
+
+
+
+Methods inherited from class java.lang.Object
+clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+DynamicPath
+public DynamicPath(java.awt.geom.PathIterator pathIterator,
+ int lineSize,
+ java.awt.Color color,
+ Robot robot)
+Constructor
+
+Parameters:
+pathIterator - a PathIterator describing the path
+lineSize - the line width used to draw the path.
+color - the color used to draw the path
+robot - a Robot that moves along the path
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/curves/Line.html b/doc/org/jointheleague/graphical/robot/curves/Line.html
new file mode 100644
index 0000000..ceb3052
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/curves/Line.html
@@ -0,0 +1,502 @@
+
+
+
+
+
+Line
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+Line (float x,
+ float y,
+ float[] ctrlPoints,
+ int lineSize,
+ java.awt.Color color)
+Constructor
+
+
+
+
+
+
+
+
+
+
+Method Summary
+
+All Methods Instance Methods Concrete Methods
+
+Modifier and Type
+Method and Description
+
+
+java.awt.geom.Path2D
+addTo (java.awt.geom.Path2D path2D)
+Adds the Segment to the end of a Path2D
+
+
+
+java.awt.geom.Path2D
+addTo (java.awt.geom.Path2D path2D,
+ float t)
+Adds a sub-segment of this segment to the end of a Path2D
+
+
+
+void
+draw (java.awt.Graphics2D g2)
+Draws the drawable given a graphics context
+
+
+
+double
+getAngle (float t)
+Gets the angle of the segment in radians at the position specified by time
+
+
+
+double
+getEndAngle ()
+
+
+Robot.Pos
+getPos (float t)
+Return the position on the segment at time t.
+
+
+
+float
+getSize ()
+The time a robot uses to trace a segment at a given speed is
+ proportional to the segment's size.
+
+
+
+double
+getStartAngle ()
+
+
+Segment
+subSegment (float t)
+Return the sub-segment of this segment that starts at 0 and ends at t.
+
+
+
+
+
+
+
+Methods inherited from class java.lang.Object
+clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+Line
+public Line(float x,
+ float y,
+ float[] ctrlPoints,
+ int lineSize,
+ java.awt.Color color)
+Constructor
+
+Parameters:
+x - x-coordinate of the segment's starting point
+y - y-coordinate of the segment's starting point
+ctrlPoints - an array of length at least 2 that
+ contains the x- and y-coordinates of the segment's control points.
+lineSize - the line width used to draw the segment
+color - the color used to draw the segment
+
+
+
+
+
+
+
+
+
+
+Method Detail
+
+
+
+
+
+
+
+
+
+subSegment
+public Segment subSegment(float t)
+Description copied from interface: Segment
+Return the sub-segment of this segment that starts at 0 and ends at t.
+ For t ≤ 0, returns a segment of size 0, and for t ≥ 1F,
+ returns this.
+
+Specified by:
+subSegment in interface Segment
+Parameters:
+t - a float value, normally between 0 and 1
+Returns:
+A sub-segment of this segment
+
+
+
+
+
+
+
+
+getPos
+public Robot.Pos getPos(float t)
+Description copied from interface: Segment
+Return the position on the segment at time t. If t ≤ 0,
+ the start position of this segment is returned, and if t ≥ 1, the end
+ position of this segment is returned.
+
+Specified by:
+getPos in interface Segment
+Parameters:
+t - a float value, normally between 0 and 1
+Returns:
+A position on this segment
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+addTo
+public java.awt.geom.Path2D addTo(java.awt.geom.Path2D path2D,
+ float t)
+Description copied from interface: Segment
+Adds a sub-segment of this segment to the end of a Path2D
+
+Specified by:
+addTo in interface Segment
+Parameters:
+path2D - a Path2D to which the sub-segment is added
+t - a float value, normally between 0 and 1, that
+ specifies the sub-segment of this segment that is added
+Returns:
+a Path2D
+See Also:
+Segment.subSegment(float)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/curves/Move.html b/doc/org/jointheleague/graphical/robot/curves/Move.html
new file mode 100644
index 0000000..63435ef
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/curves/Move.html
@@ -0,0 +1,473 @@
+
+
+
+
+
+Move
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+Move (float x,
+ float y,
+ float[] ctrlPoints)
+Constructor.
+
+
+
+
+
+
+
+
+
+
+Method Summary
+
+All Methods Instance Methods Concrete Methods
+
+Modifier and Type
+Method and Description
+
+
+java.awt.geom.Path2D
+addTo (java.awt.geom.Path2D path2D)
+Adds the Segment to the end of a Path2D
+
+
+
+java.awt.geom.Path2D
+addTo (java.awt.geom.Path2D path2D,
+ float t)
+Adds a sub-segment of this segment to the end of a Path2D
+
+
+
+double
+getAngle (float t)
+Gets the angle of the segment in radians at the position specified by time
+
+
+
+double
+getEndAngle ()
+
+
+Robot.Pos
+getPos (float t)
+Return the position on the segment at time t.
+
+
+
+float
+getSize ()
+The time a robot uses to trace a segment at a given speed is
+ proportional to the segment's size.
+
+
+
+double
+getStartAngle ()
+
+
+Segment
+subSegment (float t)
+Return the sub-segment of this segment that starts at 0 and ends at t.
+
+
+
+
+
+
+
+Methods inherited from class java.lang.Object
+clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+Move
+public Move(float x,
+ float y,
+ float[] ctrlPoints)
+Constructor. This segment is not drawn.
+
+Parameters:
+x - x-coordinate of the segment's starting point
+y - y-coordinate of the segment's starting point
+ctrlPoints - an array of length at least 2 that
+ contains the x- and y-coordinates of the segment's control points.
+
+
+
+
+
+
+
+
+
+
+Method Detail
+
+
+
+
+
+subSegment
+public Segment subSegment(float t)
+Description copied from interface: Segment
+Return the sub-segment of this segment that starts at 0 and ends at t.
+ For t ≤ 0, returns a segment of size 0, and for t ≥ 1F,
+ returns this.
+
+Specified by:
+subSegment in interface Segment
+Parameters:
+t - a float value, normally between 0 and 1
+Returns:
+A sub-segment of this segment
+
+
+
+
+
+
+
+
+getPos
+public Robot.Pos getPos(float t)
+Description copied from interface: Segment
+Return the position on the segment at time t. If t ≤ 0,
+ the start position of this segment is returned, and if t ≥ 1, the end
+ position of this segment is returned.
+
+Specified by:
+getPos in interface Segment
+Parameters:
+t - a float value, normally between 0 and 1
+Returns:
+A position on this segment
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+addTo
+public java.awt.geom.Path2D addTo(java.awt.geom.Path2D path2D,
+ float t)
+Description copied from interface: Segment
+Adds a sub-segment of this segment to the end of a Path2D
+
+Specified by:
+addTo in interface Segment
+Parameters:
+path2D - a Path2D to which the sub-segment is added
+t - a float value, normally between 0 and 1, that
+ specifies the sub-segment of this segment that is added
+Returns:
+a Path2D
+See Also:
+Segment.subSegment(float)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/curves/PartialPath.html b/doc/org/jointheleague/graphical/robot/curves/PartialPath.html
new file mode 100644
index 0000000..18b2bc2
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/curves/PartialPath.html
@@ -0,0 +1,328 @@
+
+
+
+
+
+PartialPath
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+All Implemented Interfaces:
+Drawable
+
+
+
+public final class PartialPath
+extends java.lang.Object
+implements Drawable
+A Path that is followed by a Robot. Only the part of the path from
+ the path's start to the robot's current position is drawn.
+
+
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+PartialPath (java.awt.geom.PathIterator pathIterator,
+ int lineSize,
+ java.awt.Color color,
+ Robot robot)
+Constructor
+
+
+
+
+
+
+
+
+
+
+Method Summary
+
+
+
+
+
+Methods inherited from class java.lang.Object
+clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+PartialPath
+public PartialPath(java.awt.geom.PathIterator pathIterator,
+ int lineSize,
+ java.awt.Color color,
+ Robot robot)
+Constructor
+
+Parameters:
+pathIterator - a PathIterator describing the path
+lineSize - the line width used to draw the path.
+color - the color used to draw the path
+robot - a Robot that moves along the path
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/curves/Quad.html b/doc/org/jointheleague/graphical/robot/curves/Quad.html
new file mode 100644
index 0000000..98e1cac
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/curves/Quad.html
@@ -0,0 +1,502 @@
+
+
+
+
+
+Quad
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+Quad (float x,
+ float y,
+ float[] ctrlPoints,
+ int lineSize,
+ java.awt.Color color)
+Constructor
+
+
+
+
+
+
+
+
+
+
+Method Summary
+
+All Methods Instance Methods Concrete Methods
+
+Modifier and Type
+Method and Description
+
+
+java.awt.geom.Path2D
+addTo (java.awt.geom.Path2D path2D)
+Adds the Segment to the end of a Path2D
+
+
+
+java.awt.geom.Path2D
+addTo (java.awt.geom.Path2D path2D,
+ float t)
+Adds a sub-segment of this segment to the end of a Path2D
+
+
+
+void
+draw (java.awt.Graphics2D g2)
+Draws the drawable given a graphics context
+
+
+
+double
+getAngle (float time)
+Gets the angle of the segment in radians at the position specified by time
+
+
+
+double
+getEndAngle ()
+
+
+Robot.Pos
+getPos (float t)
+Return the position on the segment at time t.
+
+
+
+float
+getSize ()
+The time a robot uses to trace a segment at a given speed is
+ proportional to the segment's size.
+
+
+
+double
+getStartAngle ()
+
+
+Segment
+subSegment (float t)
+Return the sub-segment of this segment that starts at 0 and ends at t.
+
+
+
+
+
+
+
+Methods inherited from class java.lang.Object
+clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+Quad
+public Quad(float x,
+ float y,
+ float[] ctrlPoints,
+ int lineSize,
+ java.awt.Color color)
+Constructor
+
+Parameters:
+x - x-coordinate of the segment's starting point
+y - y-coordinate of the segment's starting point
+ctrlPoints - an array of length at least 4 that
+ contains the x- and y-coordinates of the segment's control points.
+lineSize - the line width used to draw the segment
+color - the color used to draw the segment
+
+
+
+
+
+
+
+
+
+
+Method Detail
+
+
+
+
+
+
+
+
+
+subSegment
+public Segment subSegment(float t)
+Description copied from interface: Segment
+Return the sub-segment of this segment that starts at 0 and ends at t.
+ For t ≤ 0, returns a segment of size 0, and for t ≥ 1F,
+ returns this.
+
+Specified by:
+subSegment in interface Segment
+Parameters:
+t - a float value, normally between 0 and 1
+Returns:
+A sub-segment of this segment
+
+
+
+
+
+
+
+
+getPos
+public Robot.Pos getPos(float t)
+Description copied from interface: Segment
+Return the position on the segment at time t. If t ≤ 0,
+ the start position of this segment is returned, and if t ≥ 1, the end
+ position of this segment is returned.
+
+Specified by:
+getPos in interface Segment
+Parameters:
+t - a float value, normally between 0 and 1
+Returns:
+A position on this segment
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+addTo
+public java.awt.geom.Path2D addTo(java.awt.geom.Path2D path2D,
+ float t)
+Description copied from interface: Segment
+Adds a sub-segment of this segment to the end of a Path2D
+
+Specified by:
+addTo in interface Segment
+Parameters:
+path2D - a Path2D to which the sub-segment is added
+t - a float value, normally between 0 and 1, that
+ specifies the sub-segment of this segment that is added
+Returns:
+a Path2D
+See Also:
+Segment.subSegment(float)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/curves/Segment.html b/doc/org/jointheleague/graphical/robot/curves/Segment.html
new file mode 100644
index 0000000..0d86089
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/curves/Segment.html
@@ -0,0 +1,387 @@
+
+
+
+
+
+Segment
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
+Summary:
+Nested |
+Field |
+Constr |
+Method
+
+
+Detail:
+Field |
+Constr |
+Method
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Method Summary
+
+All Methods Instance Methods Abstract Methods
+
+Modifier and Type
+Method and Description
+
+
+java.awt.geom.Path2D
+addTo (java.awt.geom.Path2D path2D)
+Adds the Segment to the end of a Path2D
+
+
+
+java.awt.geom.Path2D
+addTo (java.awt.geom.Path2D path2D,
+ float t)
+Adds a sub-segment of this segment to the end of a Path2D
+
+
+
+double
+getAngle (float time)
+Gets the angle of the segment in radians at the position specified by time
+
+
+
+double
+getEndAngle ()
+
+
+Robot.Pos
+getPos (float t)
+Return the position on the segment at time t.
+
+
+
+float
+getSize ()
+The time a robot uses to trace a segment at a given speed is
+ proportional to the segment's size.
+
+
+
+double
+getStartAngle ()
+
+
+Segment
+subSegment (float t)
+Return the sub-segment of this segment that starts at 0 and ends at t.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Method Detail
+
+
+
+
+
+subSegment
+Segment subSegment(float t)
+Return the sub-segment of this segment that starts at 0 and ends at t.
+ For t ≤ 0, returns a segment of size 0, and for t ≥ 1F,
+ returns this.
+
+Parameters:
+t - a float value, normally between 0 and 1
+Returns:
+A sub-segment of this segment
+
+
+
+
+
+
+
+
+getPos
+Robot.Pos getPos(float t)
+Return the position on the segment at time t. If t ≤ 0,
+ the start position of this segment is returned, and if t ≥ 1, the end
+ position of this segment is returned.
+
+Parameters:
+t - a float value, normally between 0 and 1
+Returns:
+A position on this segment
+
+
+
+
+
+
+
+
+
+
+
+
+getEndAngle
+double getEndAngle()
+
+Returns:
+the angle in radians of the segment at the end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+addTo
+java.awt.geom.Path2D addTo(java.awt.geom.Path2D path2D,
+ float t)
+Adds a sub-segment of this segment to the end of a Path2D
+
+Parameters:
+path2D - a Path2D to which the sub-segment is added
+t - a float value, normally between 0 and 1, that
+ specifies the sub-segment of this segment that is added
+Returns:
+a Path2D
+See Also:
+subSegment(float)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Summary:
+Nested |
+Field |
+Constr |
+Method
+
+
+Detail:
+Field |
+Constr |
+Method
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/curves/package-frame.html b/doc/org/jointheleague/graphical/robot/curves/package-frame.html
new file mode 100644
index 0000000..4a391bc
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/curves/package-frame.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+org.jointheleague.graphical.robot.curves
+
+
+
+
+
+
+
+
Interfaces
+
+
Classes
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/curves/package-summary.html b/doc/org/jointheleague/graphical/robot/curves/package-summary.html
new file mode 100644
index 0000000..8d28f35
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/curves/package-summary.html
@@ -0,0 +1,181 @@
+
+
+
+
+
+org.jointheleague.graphical.robot.curves
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+Interface Summary
+
+Interface
+Description
+
+
+
+Drawable
+
+
+
+Segment
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/curves/package-tree.html b/doc/org/jointheleague/graphical/robot/curves/package-tree.html
new file mode 100644
index 0000000..9994b8e
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/curves/package-tree.html
@@ -0,0 +1,145 @@
+
+
+
+
+
+org.jointheleague.graphical.robot.curves Class Hierarchy
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
Class Hierarchy
+
+java.lang.Object
+
+org.jointheleague.graphical.robot.curves.Close (implements org.jointheleague.graphical.robot.curves.Segment )
+org.jointheleague.graphical.robot.curves.Cubic (implements org.jointheleague.graphical.robot.curves.Drawable , org.jointheleague.graphical.robot.curves.Segment )
+org.jointheleague.graphical.robot.curves.DynamicPath (implements org.jointheleague.graphical.robot.curves.Drawable )
+org.jointheleague.graphical.robot.curves.Line (implements org.jointheleague.graphical.robot.curves.Drawable , org.jointheleague.graphical.robot.curves.Segment )
+org.jointheleague.graphical.robot.curves.Move (implements org.jointheleague.graphical.robot.curves.Segment )
+org.jointheleague.graphical.robot.curves.Quad (implements org.jointheleague.graphical.robot.curves.Drawable , org.jointheleague.graphical.robot.curves.Segment )
+
+
+
+
Interface Hierarchy
+
+org.jointheleague.graphical.robot.curves.Drawable
+org.jointheleague.graphical.robot.curves.Segment
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/package-frame.html b/doc/org/jointheleague/graphical/robot/package-frame.html
new file mode 100644
index 0000000..687fe32
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/package-frame.html
@@ -0,0 +1,28 @@
+
+
+
+
+
+org.jointheleague.graphical.robot
+
+
+
+
+
+
+
+
Interfaces
+
+
Classes
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/package-summary.html b/doc/org/jointheleague/graphical/robot/package-summary.html
new file mode 100644
index 0000000..6ff9c91
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/package-summary.html
@@ -0,0 +1,181 @@
+
+
+
+
+
+org.jointheleague.graphical.robot
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+Interface Summary
+
+Interface
+Description
+
+
+
+RobotInterface
+
+
+
+
+
+
+
+Class Summary
+
+Class
+Description
+
+
+
+KeyboardAdapter
+
+
+ This class is used to control a robot through key presses.
+
+
+
+Robot
+
+
+ This class is used to show a robot inside a window.
+
+
+
+Robot.Pos
+
+
+
+RobotImage
+
+Utility class for loading images in robi format.
+
+
+
+RobotWindow
+
+Singleton class that defines the window in which the Robots move around.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/org/jointheleague/graphical/robot/package-tree.html b/doc/org/jointheleague/graphical/robot/package-tree.html
new file mode 100644
index 0000000..21ecbfe
--- /dev/null
+++ b/doc/org/jointheleague/graphical/robot/package-tree.html
@@ -0,0 +1,159 @@
+
+
+
+
+
+org.jointheleague.graphical.robot Class Hierarchy
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
Class Hierarchy
+
+java.lang.Object
+
+java.awt.Component (implements java.awt.image.ImageObserver, java.awt.MenuContainer, java.io.Serializable)
+
+java.awt.Container
+
+javax.swing.JComponent (implements java.io.Serializable)
+
+javax.swing.JPanel (implements javax.accessibility.Accessible)
+
+
+
+
+
+
+
+
+org.jointheleague.graphical.robot.KeyboardAdapter (implements java.awt.event.KeyListener, java.lang.Runnable)
+org.jointheleague.graphical.robot.Robot (implements org.jointheleague.graphical.robot.RobotInterface )
+org.jointheleague.graphical.robot.Robot.Pos
+org.jointheleague.graphical.robot.RobotImage
+
+
+
+
Interface Hierarchy
+
+
+
+
+
+
+
+
diff --git a/doc/overview-frame.html b/doc/overview-frame.html
new file mode 100644
index 0000000..0210710
--- /dev/null
+++ b/doc/overview-frame.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+Overview List
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/overview-summary.html b/doc/overview-summary.html
new file mode 100644
index 0000000..bfcc456
--- /dev/null
+++ b/doc/overview-summary.html
@@ -0,0 +1,137 @@
+
+
+
+
+
+Overview
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/overview-tree.html b/doc/overview-tree.html
new file mode 100644
index 0000000..fcd13b1
--- /dev/null
+++ b/doc/overview-tree.html
@@ -0,0 +1,168 @@
+
+
+
+
+
+Class Hierarchy
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
Class Hierarchy
+
+java.lang.Object
+
+org.jointheleague.graphical.robot.curves.Close (implements org.jointheleague.graphical.robot.curves.Segment )
+java.awt.Component (implements java.awt.image.ImageObserver, java.awt.MenuContainer, java.io.Serializable)
+
+java.awt.Container
+
+javax.swing.JComponent (implements java.io.Serializable)
+
+javax.swing.JPanel (implements javax.accessibility.Accessible)
+
+
+
+
+
+
+
+
+org.jointheleague.graphical.robot.curves.Cubic (implements org.jointheleague.graphical.robot.curves.Drawable , org.jointheleague.graphical.robot.curves.Segment )
+org.jointheleague.graphical.robot.curves.DynamicPath (implements org.jointheleague.graphical.robot.curves.Drawable )
+org.jointheleague.graphical.robot.KeyboardAdapter (implements java.awt.event.KeyListener, java.lang.Runnable)
+org.jointheleague.graphical.robot.curves.Line (implements org.jointheleague.graphical.robot.curves.Drawable , org.jointheleague.graphical.robot.curves.Segment )
+org.jointheleague.graphical.robot.curves.Move (implements org.jointheleague.graphical.robot.curves.Segment )
+org.jointheleague.graphical.robot.curves.Quad (implements org.jointheleague.graphical.robot.curves.Drawable , org.jointheleague.graphical.robot.curves.Segment )
+org.jointheleague.graphical.robot.Robot (implements org.jointheleague.graphical.robot.RobotInterface )
+org.jointheleague.graphical.robot.Robot.Pos
+org.jointheleague.graphical.robot.RobotImage
+
+
+
+
Interface Hierarchy
+
+org.jointheleague.graphical.robot.curves.Drawable
+org.jointheleague.graphical.robot.RobotInterface
+org.jointheleague.graphical.robot.curves.Segment
+
+
+
+
+
+
+
+
diff --git a/doc/package-list b/doc/package-list
new file mode 100644
index 0000000..2079005
--- /dev/null
+++ b/doc/package-list
@@ -0,0 +1,2 @@
+org.jointheleague.graphical.robot
+org.jointheleague.graphical.robot.curves
diff --git a/doc/script.js b/doc/script.js
new file mode 100644
index 0000000..b346356
--- /dev/null
+++ b/doc/script.js
@@ -0,0 +1,30 @@
+function show(type)
+{
+ count = 0;
+ for (var key in methods) {
+ var row = document.getElementById(key);
+ if ((methods[key] & type) != 0) {
+ row.style.display = '';
+ row.className = (count++ % 2) ? rowColor : altColor;
+ }
+ else
+ row.style.display = 'none';
+ }
+ updateTabs(type);
+}
+
+function updateTabs(type)
+{
+ for (var value in tabs) {
+ var sNode = document.getElementById(tabs[value][0]);
+ var spanNode = sNode.firstChild;
+ if (value == type) {
+ sNode.className = activeTableTab;
+ spanNode.innerHTML = tabs[value][1];
+ }
+ else {
+ sNode.className = tableTab;
+ spanNode.innerHTML = "" + tabs[value][1] + " ";
+ }
+ }
+}
diff --git a/doc/serialized-form.html b/doc/serialized-form.html
new file mode 100644
index 0000000..79e4ef7
--- /dev/null
+++ b/doc/serialized-form.html
@@ -0,0 +1,170 @@
+
+
+
+
+
+Serialized Form
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/stylesheet.css b/doc/stylesheet.css
new file mode 100644
index 0000000..98055b2
--- /dev/null
+++ b/doc/stylesheet.css
@@ -0,0 +1,574 @@
+/* Javadoc style sheet */
+/*
+Overall document style
+*/
+
+@import url('resources/fonts/dejavu.css');
+
+body {
+ background-color:#ffffff;
+ color:#353833;
+ font-family:'DejaVu Sans', Arial, Helvetica, sans-serif;
+ font-size:14px;
+ margin:0;
+}
+a:link, a:visited {
+ text-decoration:none;
+ color:#4A6782;
+}
+a:hover, a:focus {
+ text-decoration:none;
+ color:#bb7a2a;
+}
+a:active {
+ text-decoration:none;
+ color:#4A6782;
+}
+a[name] {
+ color:#353833;
+}
+a[name]:hover {
+ text-decoration:none;
+ color:#353833;
+}
+pre {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+}
+h1 {
+ font-size:20px;
+}
+h2 {
+ font-size:18px;
+}
+h3 {
+ font-size:16px;
+ font-style:italic;
+}
+h4 {
+ font-size:13px;
+}
+h5 {
+ font-size:12px;
+}
+h6 {
+ font-size:11px;
+}
+ul {
+ list-style-type:disc;
+}
+code, tt {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+ padding-top:4px;
+ margin-top:8px;
+ line-height:1.4em;
+}
+dt code {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+ padding-top:4px;
+}
+table tr td dt code {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+ vertical-align:top;
+ padding-top:4px;
+}
+sup {
+ font-size:8px;
+}
+/*
+Document title and Copyright styles
+*/
+.clear {
+ clear:both;
+ height:0px;
+ overflow:hidden;
+}
+.aboutLanguage {
+ float:right;
+ padding:0px 21px;
+ font-size:11px;
+ z-index:200;
+ margin-top:-9px;
+}
+.legalCopy {
+ margin-left:.5em;
+}
+.bar a, .bar a:link, .bar a:visited, .bar a:active {
+ color:#FFFFFF;
+ text-decoration:none;
+}
+.bar a:hover, .bar a:focus {
+ color:#bb7a2a;
+}
+.tab {
+ background-color:#0066FF;
+ color:#ffffff;
+ padding:8px;
+ width:5em;
+ font-weight:bold;
+}
+/*
+Navigation bar styles
+*/
+.bar {
+ background-color:#4D7A97;
+ color:#FFFFFF;
+ padding:.8em .5em .4em .8em;
+ height:auto;/*height:1.8em;*/
+ font-size:11px;
+ margin:0;
+}
+.topNav {
+ background-color:#4D7A97;
+ color:#FFFFFF;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+ font-size:12px;
+}
+.bottomNav {
+ margin-top:10px;
+ background-color:#4D7A97;
+ color:#FFFFFF;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+ font-size:12px;
+}
+.subNav {
+ background-color:#dee3e9;
+ float:left;
+ width:100%;
+ overflow:hidden;
+ font-size:12px;
+}
+.subNav div {
+ clear:left;
+ float:left;
+ padding:0 0 5px 6px;
+ text-transform:uppercase;
+}
+ul.navList, ul.subNavList {
+ float:left;
+ margin:0 25px 0 0;
+ padding:0;
+}
+ul.navList li{
+ list-style:none;
+ float:left;
+ padding: 5px 6px;
+ text-transform:uppercase;
+}
+ul.subNavList li{
+ list-style:none;
+ float:left;
+}
+.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {
+ color:#FFFFFF;
+ text-decoration:none;
+ text-transform:uppercase;
+}
+.topNav a:hover, .bottomNav a:hover {
+ text-decoration:none;
+ color:#bb7a2a;
+ text-transform:uppercase;
+}
+.navBarCell1Rev {
+ background-color:#F8981D;
+ color:#253441;
+ margin: auto 5px;
+}
+.skipNav {
+ position:absolute;
+ top:auto;
+ left:-9999px;
+ overflow:hidden;
+}
+/*
+Page header and footer styles
+*/
+.header, .footer {
+ clear:both;
+ margin:0 20px;
+ padding:5px 0 0 0;
+}
+.indexHeader {
+ margin:10px;
+ position:relative;
+}
+.indexHeader span{
+ margin-right:15px;
+}
+.indexHeader h1 {
+ font-size:13px;
+}
+.title {
+ color:#2c4557;
+ margin:10px 0;
+}
+.subTitle {
+ margin:5px 0 0 0;
+}
+.header ul {
+ margin:0 0 15px 0;
+ padding:0;
+}
+.footer ul {
+ margin:20px 0 5px 0;
+}
+.header ul li, .footer ul li {
+ list-style:none;
+ font-size:13px;
+}
+/*
+Heading styles
+*/
+div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
+ background-color:#dee3e9;
+ border:1px solid #d0d9e0;
+ margin:0 0 6px -8px;
+ padding:7px 5px;
+}
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+ background-color:#dee3e9;
+ border:1px solid #d0d9e0;
+ margin:0 0 6px -8px;
+ padding:7px 5px;
+}
+ul.blockList ul.blockList li.blockList h3 {
+ padding:0;
+ margin:15px 0;
+}
+ul.blockList li.blockList h2 {
+ padding:0px 0 20px 0;
+}
+/*
+Page layout container styles
+*/
+.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {
+ clear:both;
+ padding:10px 20px;
+ position:relative;
+}
+.indexContainer {
+ margin:10px;
+ position:relative;
+ font-size:12px;
+}
+.indexContainer h2 {
+ font-size:13px;
+ padding:0 0 3px 0;
+}
+.indexContainer ul {
+ margin:0;
+ padding:0;
+}
+.indexContainer ul li {
+ list-style:none;
+ padding-top:2px;
+}
+.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
+ font-size:12px;
+ font-weight:bold;
+ margin:10px 0 0 0;
+ color:#4E4E4E;
+}
+.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
+ margin:5px 0 10px 0px;
+ font-size:14px;
+ font-family:'DejaVu Sans Mono',monospace;
+}
+.serializedFormContainer dl.nameValue dt {
+ margin-left:1px;
+ font-size:1.1em;
+ display:inline;
+ font-weight:bold;
+}
+.serializedFormContainer dl.nameValue dd {
+ margin:0 0 0 1px;
+ font-size:1.1em;
+ display:inline;
+}
+/*
+List styles
+*/
+ul.horizontal li {
+ display:inline;
+ font-size:0.9em;
+}
+ul.inheritance {
+ margin:0;
+ padding:0;
+}
+ul.inheritance li {
+ display:inline;
+ list-style:none;
+}
+ul.inheritance li ul.inheritance {
+ margin-left:15px;
+ padding-left:15px;
+ padding-top:1px;
+}
+ul.blockList, ul.blockListLast {
+ margin:10px 0 10px 0;
+ padding:0;
+}
+ul.blockList li.blockList, ul.blockListLast li.blockList {
+ list-style:none;
+ margin-bottom:15px;
+ line-height:1.4;
+}
+ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {
+ padding:0px 20px 5px 10px;
+ border:1px solid #ededed;
+ background-color:#f8f8f8;
+}
+ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {
+ padding:0 0 5px 8px;
+ background-color:#ffffff;
+ border:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockList {
+ margin-left:0;
+ padding-left:0;
+ padding-bottom:15px;
+ border:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
+ list-style:none;
+ border-bottom:none;
+ padding-bottom:0;
+}
+table tr td dl, table tr td dl dt, table tr td dl dd {
+ margin-top:0;
+ margin-bottom:1px;
+}
+/*
+Table styles
+*/
+.overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary {
+ width:100%;
+ border-left:1px solid #EEE;
+ border-right:1px solid #EEE;
+ border-bottom:1px solid #EEE;
+}
+.overviewSummary, .memberSummary {
+ padding:0px;
+}
+.overviewSummary caption, .memberSummary caption, .typeSummary caption,
+.useSummary caption, .constantsSummary caption, .deprecatedSummary caption {
+ position:relative;
+ text-align:left;
+ background-repeat:no-repeat;
+ color:#253441;
+ font-weight:bold;
+ clear:none;
+ overflow:hidden;
+ padding:0px;
+ padding-top:10px;
+ padding-left:1px;
+ margin:0px;
+ white-space:pre;
+}
+.overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link,
+.useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link,
+.overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover,
+.useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover,
+.overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active,
+.useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active,
+.overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited,
+.useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited {
+ color:#FFFFFF;
+}
+.overviewSummary caption span, .memberSummary caption span, .typeSummary caption span,
+.useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ padding-bottom:7px;
+ display:inline-block;
+ float:left;
+ background-color:#F8981D;
+ border: none;
+ height:16px;
+}
+.memberSummary caption span.activeTableTab span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ margin-right:3px;
+ display:inline-block;
+ float:left;
+ background-color:#F8981D;
+ height:16px;
+}
+.memberSummary caption span.tableTab span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ margin-right:3px;
+ display:inline-block;
+ float:left;
+ background-color:#4D7A97;
+ height:16px;
+}
+.memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab {
+ padding-top:0px;
+ padding-left:0px;
+ padding-right:0px;
+ background-image:none;
+ float:none;
+ display:inline;
+}
+.overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd,
+.useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd {
+ display:none;
+ width:5px;
+ position:relative;
+ float:left;
+ background-color:#F8981D;
+}
+.memberSummary .activeTableTab .tabEnd {
+ display:none;
+ width:5px;
+ margin-right:3px;
+ position:relative;
+ float:left;
+ background-color:#F8981D;
+}
+.memberSummary .tableTab .tabEnd {
+ display:none;
+ width:5px;
+ margin-right:3px;
+ position:relative;
+ background-color:#4D7A97;
+ float:left;
+
+}
+.overviewSummary td, .memberSummary td, .typeSummary td,
+.useSummary td, .constantsSummary td, .deprecatedSummary td {
+ text-align:left;
+ padding:0px 0px 12px 10px;
+}
+th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th,
+td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{
+ vertical-align:top;
+ padding-right:0px;
+ padding-top:8px;
+ padding-bottom:3px;
+}
+th.colFirst, th.colLast, th.colOne, .constantsSummary th {
+ background:#dee3e9;
+ text-align:left;
+ padding:8px 3px 3px 7px;
+}
+td.colFirst, th.colFirst {
+ white-space:nowrap;
+ font-size:13px;
+}
+td.colLast, th.colLast {
+ font-size:13px;
+}
+td.colOne, th.colOne {
+ font-size:13px;
+}
+.overviewSummary td.colFirst, .overviewSummary th.colFirst,
+.useSummary td.colFirst, .useSummary th.colFirst,
+.overviewSummary td.colOne, .overviewSummary th.colOne,
+.memberSummary td.colFirst, .memberSummary th.colFirst,
+.memberSummary td.colOne, .memberSummary th.colOne,
+.typeSummary td.colFirst{
+ width:25%;
+ vertical-align:top;
+}
+td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover {
+ font-weight:bold;
+}
+.tableSubHeadingColor {
+ background-color:#EEEEFF;
+}
+.altColor {
+ background-color:#FFFFFF;
+}
+.rowColor {
+ background-color:#EEEEEF;
+}
+/*
+Content styles
+*/
+.description pre {
+ margin-top:0;
+}
+.deprecatedContent {
+ margin:0;
+ padding:10px 0;
+}
+.docSummary {
+ padding:0;
+}
+
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+ font-style:normal;
+}
+
+div.block {
+ font-size:14px;
+ font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif;
+}
+
+td.colLast div {
+ padding-top:0px;
+}
+
+
+td.colLast a {
+ padding-bottom:3px;
+}
+/*
+Formatting effect styles
+*/
+.sourceLineNo {
+ color:green;
+ padding:0 30px 0 0;
+}
+h1.hidden {
+ visibility:hidden;
+ overflow:hidden;
+ font-size:10px;
+}
+.block {
+ display:block;
+ margin:3px 10px 2px 0px;
+ color:#474747;
+}
+.deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink,
+.overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel,
+.seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink {
+ font-weight:bold;
+}
+.deprecationComment, .emphasizedPhrase, .interfaceName {
+ font-style:italic;
+}
+
+div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase,
+div.block div.block span.interfaceName {
+ font-style:normal;
+}
+
+div.contentContainer ul.blockList li.blockList h2{
+ padding-bottom:0px;
+}
diff --git a/examples/Examples.iml b/examples/Examples.iml
new file mode 100644
index 0000000..da1d534
--- /dev/null
+++ b/examples/Examples.iml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/res/homer-simpson.txt b/examples/res/homer-simpson.txt
new file mode 100644
index 0000000..f56cb80
--- /dev/null
+++ b/examples/res/homer-simpson.txt
@@ -0,0 +1,348 @@
+M478.082,313.561
+c0.055,29.049-10.204,53.193-20.323,74.986
+c-0.904,0.968-3.042,0.695-4.906,0.701
+c-2.628,29.428-5.054,68.673-28.033,77.092
+c-8.332,3.056-15.768-0.871-20.324-6.31
+c-10.154-12.117-13.328-34.586-17.519-52.562
+c-1.543-1.255-4.998-0.609-7.01-1.4
+c-6.132-9.835-14.485-34.546,0.702-39.948
+c-5.754-7.057,6.504-14.346,6.308-24.528
+c-17.152,14.155-33.507,35.174-56.769,45.552
+c-4.346,27.044-10.556,48.742-21.026,68.682
+c-9.67,18.431-26.594,37.341-51.159,37.844
+c-41.193,0.854-62.947-29.286-70.782-64.477
+c-2.138-9.588-6.027-21.283,2.103-25.229
+c-16.917-11.403-37.585-29.708-39.947-56.766
+c-0.869-9.986-0.223-20.388,5.607-25.231
+c7.078-1.338,15.096-0.414,21.725,0.701
+c-1.156-9.118-2.719-17.836-3.502-27.333
+c-3.702,0.799-7.738,4.5-11.916,4.204
+c-4.702-0.321-7.583-6.117-11.213-7.008
+c-2.726-0.665-5.55,0.588-8.41,0.7
+c-36.239,1.451-74.477-21.172-84.8-50.459
+c-10.338-5.103-21.109-13.436-18.221-29.436
+c-14.737,7.254-23.28-8.458-14.017-16.821
+c5.103-4.604,14.746-3.111,21.026,0
+c3.791-5.788,8.712-10.442,18.921-9.812
+c-0.077-8.249-5.698-14.184-2.803-23.126
+c17.366-9.503,22.517,15.18,25.23,29.433
+c10.856,2.384,18.446,10.442,14.717,25.231
+c7.892,3.791,17.359,6.005,28.734,6.306
+c0.295-18.158,20.542-16.363,37.844-17.52
+c2.643-25.658-5.705-45.862-21.025-57.467
+c-11.789,4.688-24.052-6.54-18.922-18.922
+c-3.602-3.476-14.212-3.441-20.323-2.102
+c2.221,7.589,11.507,8.123,14.717,14.717
+c-6.763-3.98-14.185-7.302-16.821-15.417
+c2.285-3.083,8.852-1.892,14.017-2.103
+c-21.747-15.159-50.382-23.443-58.167-52.561
+c-8.592-4.696-23.708-24.312-13.315-37.144
+c1.198-1.472,3.868-2.634,6.307-3.505
+c-1.71-16.477,11.864-26.323,26.63-19.623
+c17.121-16.546,55.196-9.047,69.381,4.905
+c4.473-3.475,12.945-3.329,14.718,2.804
+c18.48-8.418,36.191,4.393,36.442,23.126
+c4.381,1.695,7.344,4.801,9.11,9.11
+c6.293-2.614,5.012-10.442,12.615-10.512
+c14.149-0.126,12.439,25.923,3.504,32.939
+c3.869,7.07,1.051,15.895-8.411,15.418
+c-1.059,2.915-1.731,6.215-3.505,8.411
+c-2.74,0.763-5.138,1.872-9.11,1.401
+c-1.977,9.51-0.387,21.368,4.205,26.63
+c3.946-0.203,7.093-0.244,9.11,2.104
+c1.731,3.322-1.745,6.18,0,9.11
+c7.688-5.081,21.648-2.305,15.418,9.11
+c3.097-2.277,6.3-4.443,9.111-7.008
+c8.107,4.044,14.325,9.966,22.425,14.015
+c0.491,3.764-2.074,4.473-2.804,7.009
+c8.089-6.862,19.633-10.273,32.939-11.914
+c4.297,3.182,8.27,6.686,11.913,10.512
+c15.222-5.718,34.572-16.596,44.151-32.939
+c3.049-5.193,7.956-13.532,7.008-18.221
+c-1.471-7.294-12.354-4.912-17.519-9.812
+c-5.18-12.916,13.882-14.541,21.025-9.11
+c3.321-0.883,4.301-4.107,7.008-5.606
+c-1.527-5.944-5.243-9.715-4.205-18.223
+c6.446-12.846,22.084-4.254,23.828,7.009
+c15.241-10,23.645,11.003,9.109,17.521
+c2.88,11.494,19.021,8.41,30.135,8.41
+c9.791,11.459-5.558,21.13-16.819,22.426
+c-11.964,15.593-16.939,35.546-26.631,52.563
+c-9.655,16.952-21.81,30.423-35.742,42.75
+c9.824,6.994,19.253,14.387,27.334,23.127
+C434.609,227.906,477.984,260.298,478.082,313.561
+z
+
+M196.352,73.178
+c5.999-5.859,20.534-23.533,7.008-27.332
+c-13.891-3.889-20.232,17.022-28.032,20.324
+c3.56,18.158-10.568,29.771-21.726,30.836
+c-35.208,3.378-37.312-52.913-2.101-51.861
+c-0.653-12.796,6.18-18.116,11.913-24.529
+c-1.885-4.723-10.246-2.704-12.615,0
+c-10.288-7.344-20.737-14.184-35.741-15.418
+C85.547,2.779,71.762,24.385,64.599,46.546
+c1.023,2.951,5.376,2.573,6.307,5.607
+c-3.413,1.03-6.068-5.222-7.008-2.104
+c-1.899,4.85-1.92,14.605-0.701,20.324
+c1.121,2.383,5.872,1.135,6.308,4.205
+c-2.523,0.188-3.379-1.291-5.607-1.402
+c8.423,28.727,37.255,37.038,59.57,51.861
+c-2.081-5.86-7.33-8.549-7.008-16.821
+c8.067-3.083,19.105,2.167,24.529,6.308
+c-8.193-1.045-15.215-6.581-23.127-5.607
+c1.816,8.698,7.029,13.995,11.915,19.624
+c1.976-3.189,8.935-7.989,12.616-4.905
+c-18.264,0.679-16.19,27.556,1.402,25.229
+c7.358-0.974,7.54-9.917,12.615-11.914
+c-1.563,4.746-4.015,8.599-7.009,11.914
+c11.676,10.05,20.135,23.316,21.726,43.451
+c10.072-6.279,19.721-12.986,29.436-19.623
+c-25.25-6.244-40.908-22.643-38.546-49.757
+C164.155,98.38,183.975,85.261,196.352,73.178
+z
+
+M169.02,286.229
+c0.154-27.018-5.234-48.498-16.82-63.775
+c-14.395,7.113-37.284,3.771-51.162-1.402
+c-1.737,0.834-0.847,4.297-4.205,3.504
+c2.754-8.15,6.609-17.066,1.402-23.828
+c-7.604-9.867-30.619-4.366-28.033,8.41
+c2.123,10.499,18.789,3.379,21.726,0
+c-3.603,9.939-22.854,10.611-23.829-0.7
+c-0.728-8.445,7.485-13.813,16.819-14.717
+c-3.145-12.881-4.688-34.362-21.023-29.436
+c-3.665,9.896,6.433,19.083,2.102,27.333
+c-1.857,0.224,0.659-3.925-2.102-2.803
+c-22.566-5.389-20.177,32.875-6.309,32.938
+c11.41,0.057,6.344-16.237,5.607-23.126
+c6.819,8.557,4.941,25.265-5.607,25.229
+c-10.351-0.036-12.229-14.087-12.615-25.931
+c-9.721-4.113-24.984-3.049-21.726,11.915
+c4.97,6.987,16.141-1.675,21.025,1.402
+c-0.126,3.307-3.778-1.256-3.505,2.101
+c-3.734,19.904,13.142,25.132,25.23,31.538
+c-3.098,1.471-6.209-2.965-6.307,0
+C74.675,278.877,121.637,300.111,169.02,286.229
+z
+
+M375.061,241.375
+c-11.929-13.854-28.215-28.438-51.861-30.135
+c-5.453-0.386-14.463,1.268-18.923-0.7
+c2.277-0.057,4.311-0.357,5.609-1.402
+c-15.687-18.894-36.746-32.398-60.272-43.451
+c2.584-1.528,4.906,2.312,8.409,2.104
+c1.683-4.394,4.696-7.45,6.307-11.914
+c-6.02-4.954-12.508-9.448-19.621-13.315
+c-0.126,10.68,4.792,19.924,2.803,30.135
+c-9.139-2.305-15.508-7.386-25.229-9.11
+c-2.25,10.562,4.416,17.919,7.008,25.931
+c-8.837,11.948-23.022,18.564-36.442,25.931
+c8.668,6.958,16.329,15.838,17.52,28.733
+c2.327,25.124-20.016,39.457-35.041,49.058
+c1.037,26.764,7.232,48.364,16.82,66.578
+c42.925,0.645,76.349-8.213,102.322-24.529
+C309.113,291.766,331.616,256.101,375.061,241.375
+z
+
+M226.486,151.67
+c3.232-3.308,8.852-4.233,7.709-11.914
+c-2.768-3.995-9.7-1.29-12.614,0.701
+c-3.959-2.25-5.873-1.584-8.411,2.102
+c3.568,0.638,9.854-1.444,11.213,1.401
+c-5.192,13.484-16.525,22.86-30.835,21.024
+c-13.47-1.724-26.63-18.664-26.63-32.939
+c0-26.827,38.468-34.83,53.962-51.16
+c4.01-4.219,8.999-10.884,10.512-16.118
+c2.396-8.27-0.342-20.842-8.41-20.324
+c-6.636,0.427-7.226,10.772-11.916,11.914
+c-9.936,26.141-56.374,38.35-46.254,82.698
+c0.925,4.051,3.933,10.73,7.008,14.717
+c5.753,7.472,19.862,18.544,32.238,16.821
+c8.466-1.179,11.241-12.187,23.829-8.41
+c1.268-1.998,3.434-3.106,2.803-7.009
+C231.462,151.839,226.516,154.213,226.486,151.67
+z
+
+M464.064,369.627
+c6.771-20.282,13.071-40.376,11.214-64.478
+c-3.124-40.55-37.073-69.893-82.696-65.877
+c-27.937,2.458-48.876,18.572-63.775,35.741
+c-15.985,18.424-26.357,40.957-34.341,65.878
+c-2.277-0.491-0.49-3.952-3.506-2.102
+c-21.472,15.207-51.88,21.466-86.901,23.127
+c16.749,22.907,50.151,35.069,87.604,32.938
+c33.113-1.878,58.252-20.203,77.089-39.244
+c3.952-3.995,17.9-15.551,19.624-19.624
+c2.179-5.144-0.653-12.216,2.803-15.417
+c1.92,8.759-1.133,18.444-2.803,25.929
+C405.35,362.463,429.647,371.105,464.064,369.627
+z
+
+M411.503,119.433
+c9.271-1.844,22.077-6.371,17.521-17.521
+c-9.341-3.315-13.406,2.312-22.426-0.7
+c-17.975-6-15.502-40.466-30.835-39.947
+c-4.199,0.148-7.204,4.345-7.711,7.007
+c-1.927,10.212,7.793,12.917,4.904,23.127
+c-1.086-1.017-1.471-2.734-1.4-4.905
+c-6.791,3.588-11.136,13.028-9.11,23.128
+c-7.604,26.967-27.149,42-51.861,51.86
+c8.285,12.741,13.995,28.053,14.718,48.358
+c8.879,0.701,15.656,3.504,22.425,6.307
+c13.962-12.7,26.717-25.923,36.444-43.451
+C393.774,155.406,398.623,134.633,411.503,119.433
+z
+
+M225.084,87.896
+c2.005-2.6,4.416-8.011,0-9.812
+c-13.813,19.833-43.85,23.43-54.664,46.255
+c8.262,1.955,7.373-5.235,9.812-9.11
+c3.112,1.03,4.114,0,7.709,0
+c2.86-1.809,2.488-6.855,4.905-9.111
+c3.147,0.343,5.249-0.35,7.71-0.701
+c2.319-1.417,2.124-5.354,4.205-7.009
+c3.743,0.779,6.932,0.918,9.812-0.7
+c1.332-2.404,1.984-5.495,2.803-8.41
+C220.916,89.801,222.492,88.345,225.084,87.896
+z
+
+M290.963,477.551
+c20.477-19.433,32.236-55.267,35.741-89.004
+c-22.596,13.05-68.162,9.581-91.808,0
+c2.137,11.613-0.827,23.296-4.206,32.236
+c-2.397,6.352-4.535,13.976-9.11,15.419
+c2.895-8.788,9.727-17.365,9.11-27.331
+c-18.515,2.509-33.059,8.998-41.348,21.726
+c7.352,32.798,28.685,58.525,63.774,60.971
+C270.112,492.753,282.355,485.725,290.963,477.551
+z
+
+M209.648,128.194
+c-0.841,0.113-17.177,2.8-19.153,11.005
+c-1.573,6.537,5.536,19.816,5.536,24.399
+c4.862,0.901,9.493-2.008,13.98-3.388
+c4.489-1.379-3.46-11.632-2.862-15.131
+c0.598-3.499,2.973-1.707,4.496-3.207
+c1.524-1.5,8.452-5.854,6.355-11.681
+C217.332,128.335,214.732,127.515,209.648,128.194
+z
+
+M227.888,188.814
+c-4.513-6.701-7.386-15.034-8.41-25.23
+c-16.567,11.003-34.972,20.155-49.757,32.939
+c0,3.505,0,7.008,0,10.512
+c7.737,1.844,15.873,3.287,21.725,7.008
+C205.286,207.33,218.827,200.307,227.888,188.814
+z
+
+M462.663,372.428
+c-33.807,0.871-57.58-8.289-75.689-23.128
+c-1.478,4.6-3.405,8.747-6.307,11.916
+c14.772,18.789,39.98,30.358,75.688,25.93
+C458.221,382.002,460.946,377.719,462.663,372.428
+z
+
+M323.199,209.838
+c0.581-20.71-8.913-44.075-21.726-54.665
+c-10.868-8.985-36.323,3.273-41.349,14.717
+c22.37,8.705,37.606,24.536,53.262,39.947
+C316.662,209.838,319.929,209.838,323.199,209.838
+z
+
+M232.093,406.769
+c1.451-5.088,0.372-12.713,0.7-18.923
+c-20.534,2.131-34.662,10.653-46.254,21.727
+c-0.127,6.202,0.721,11.431,2.101,16.119
+C198.474,417.534,211.979,406.987,232.093,406.769
+z
+
+M199.835,107.602
+c0.09,4.899,2.832,15.398,5.054,19.931
+c1.458,0.505,1.977-0.875,2.999-0.637
+c-2.851-4.037-4.401-14.389-4.401-22.195
+C202.729,105.605,199.835,106.994,199.835,107.602
+z
+
+M359.643,104.714
+c0.205-5.404,2.411-8.802,3.504-13.316
+c-6.258-2.032-20.954-5.48-19.622,5.607
+C347.078,101.394,356.201,100.216,359.643,104.714
+z
+
+M246.109,163.584
+c-2.06-6.111-0.525-15.826-4.905-19.622
+c-1.892,3.952-6.994,4.688-8.41,9.11
+C236.529,157.285,240.349,161.405,246.109,163.584
+z
+
+M246.81,170.593
+c-1.759-7.583-9.413-9.279-14.017-14.016
+c0.609,4.114-2.62,4.386-2.804,7.708
+C236.283,165.7,240.553,169.149,246.81,170.593
+z
+
+M167.618,295.338
+c18.208-9.552,44.04-25.313,41.348-51.159
+c-2.896-27.794-35.006-42.96-66.578-31.537
+C164.877,224.87,175.508,265.301,167.618,295.338
+z
+
+M200.557,43.743
+c1.745-32.014-50.79-31.495-47.656,1.401
+c11.978,1.57,18.193,8.909,22.425,18.222
+C184.052,57.142,187.436,45.572,200.557,43.743
+z
+
+M68.801,31.83
+c1.885-7.505,9.777-12.588,11.213-18.221
+c-14.087-4.71-24.073,3.588-23.127,18.221
+C60.686,30.52,64.744,31.487,68.801,31.83
+z
+
+M63.194,44.445
+c0.89-4.255,3.035-7.239,4.206-11.214
+c-4.612-0.407-5.9-0.407-10.513,0
+C57.602,38.362,58.954,42.847,63.194,44.445
+z
+
+M55.486,34.633
+c-15.573,4.751-4.878,33.954,5.607,33.64
+c-1.739-6.42-0.484-15.887,1.401-21.025
+C59.095,44.108,56.116,40.541,55.486,34.633
+z
+
+M193.546,32.53
+c0.218,2.788-1.344,3.798-4.205,3.505
+c-0.61-0.218-1.206-0.672-1.401-1.401
+C186.624,30.036,192.797,29.138,193.546,32.53
+z
+
+M150.096,77.382
+c0.218,2.789-1.345,3.799-4.206,3.505
+c-0.672-0.196-1.121-0.764-1.401-1.401
+C143.173,74.888,149.347,73.99,150.096,77.382
+z
+
+M396.785,88.596
+c14.928-4.022,5.024-23.912-6.308-12.615
+C393.227,79.542,394.509,84.567,396.785,88.596
+z
+
+M153.601,291.835
+c2.634,8.094,14.682,6.229,14.716-2.803
+C163.376,289.928,158.486,290.882,153.601,291.835
+z
+
+M147.994,95.604
+c35.398,3.441,33.863-54.426-1.401-48.357
+C119.303,51.943,122.126,93.095,147.994,95.604
+z
+
+M150.096,221.051
+c-2.523-8.15-19.771-11.97-16.821,3.504
+C140.13,224.64,145.114,222.845,150.096,221.051
+z
+
+M197.846,131.557
+c3.877,0.45,8.595-0.095,10.682,1.903
\ No newline at end of file
diff --git a/examples/res/trochoid.txt b/examples/res/trochoid.txt
new file mode 100644
index 0000000..39c851c
--- /dev/null
+++ b/examples/res/trochoid.txt
@@ -0,0 +1,14 @@
+M 372.0452 187.6190
+C 346.7498 173.7938 327.6368 149.2567 319.8492 121.5311
+C 302.4314 57.5087 355.5252 35.7060 350.3277 78.7000
+C 339.9960 130.2351 267.4785 158.6311 220.6746 139.8953
+C 210.5440 135.8855 200.6271 129.7248 195.0729 120.1206
+C 187.9243 108.0175 196.0871 97.4268 209.5460 100.4231
+C 250.8176 111.1402 265.0788 173.0956 252.8581 212.9771
+C 244.3091 247.6219 206.1747 277.5173 193.6989 258.6224
+C 183.9916 236.8302 233.5488 206.1414 287.1632 223.8577
+C 346.9719 242.5204 364.4811 304.7928 339.5012 308.1559
+C 308.7261 306.9174 305.0743 227.1659 357.5123 186.3244
+C 375.4854 170.8722 421.4886 153.7679 432.7577 179.2569
+C 437.2471 198.9650 398.1377 202.8828 372.0452 187.6190
+Z
diff --git a/examples/src/Driver.java b/examples/src/Driver.java
new file mode 100644
index 0000000..fcd03ab
--- /dev/null
+++ b/examples/src/Driver.java
@@ -0,0 +1,228 @@
+import org.jointheleague.graphical.robot.KeyboardAdapter;
+import org.jointheleague.graphical.robot.Robot;
+import org.jointheleague.graphical.robot.RobotInterface;
+
+import java.awt.*;
+import java.awt.geom.PathIterator;
+import java.awt.image.BufferedImage;
+import java.util.Random;
+
+public class Driver implements RobotInterface {
+
+ private final Robot robot;
+
+ public Driver(Robot robot) {
+ super();
+ this.robot = robot;
+ }
+
+ @Override
+ public void setSpeed(int speed) {
+ robot.setSpeed(speed);
+ }
+
+ @Override
+ public void addKeyboardAdapter(KeyboardAdapter adapter) {
+ robot.addKeyboardAdapter(adapter);
+ }
+
+ @Override
+ public void turn(double degrees) {
+ robot.turn(degrees);
+ }
+
+ @Override
+ public void turnTo(double degrees) {
+ robot.turnTo(degrees);
+ }
+
+ @Override
+ public void microTurn(int sgn) throws InterruptedException {
+ robot.microTurn(sgn);
+ }
+
+ @Override
+ public void sleep(int millis) {
+ robot.sleep(millis);
+ }
+
+ @Override @Deprecated
+ public void moveTo(float x, float y) {
+ robot.setPos(x, y);
+ }
+
+ @Override
+ public void penUp() {
+ robot.penUp();
+ }
+
+ @Override
+ public void penDown() {
+ robot.penDown();
+ }
+
+ @Override
+ public void move(int distance) {
+ robot.move(distance);
+ }
+
+ @Override
+ public void microMove(int sgn) throws InterruptedException {
+ robot.microMove(sgn);
+ }
+
+ @Override
+ public void setPos(float x, float y) {
+ robot.setPos(x, y);
+ }
+
+ @Override
+ public void moveTo(float x, float y, boolean relative) {
+ robot.moveTo(x, y, relative);
+ }
+
+ @Override
+ public void lineTo(float x, float y, boolean relative) {
+ robot.lineTo(x, y, relative);
+ }
+
+ @Override
+ public void quadTo(float x1, float y1, float x2, float y2, boolean relative) {
+
+ }
+
+ @Override
+ public void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3, boolean relative) {
+
+ }
+
+ @Override
+ public void followPath(PathIterator pathIterator, boolean fill) {
+ robot.followPath(pathIterator, fill);
+ }
+
+ @Override
+ public void followPath(PathIterator pathIterator) {
+ robot.followPath(pathIterator);
+ }
+
+ @Override
+ public float getX() {
+ return robot.getX();
+ }
+
+ @Override
+ public float getY() {
+ return robot.getY();
+ }
+
+ @Override
+ public void changeRobot(BufferedImage im) {
+ robot.changeRobot(im);
+ }
+
+ @Override
+ public void changeRobot(String urlName) {
+ robot.changeRobot(urlName);
+ }
+
+ @Override
+ public int getPenWidth() {
+ return robot.getPenWidth();
+ }
+
+ @Override
+ public void setPenWidth(int size) {
+ robot.setPenWidth(size);
+ }
+
+ @Override
+ public Color getPenColor() {
+ return robot.getPenColor();
+ }
+
+ @Override
+ public void setPenColor(Color color) {
+ robot.setPenColor(color);
+ }
+
+ @Override
+ public void setPenColor(int r, int g, int b) {
+ robot.setPenColor(r, g, b);
+ }
+
+ @Override
+ public void setRandomPenColor() {
+ int shade = 5 * new Random().nextInt(50);
+ robot.setPenColor(shade, shade, shade);
+ }
+
+ @Override
+ public void clearDrawables() {
+ robot.clearDrawables();
+ }
+
+ @Override
+ public void miniaturize() {
+ robot.miniaturize();
+ }
+
+ @Override
+ public void expand() {
+ robot.expand();
+ }
+
+ @Override
+ public double getAngle() {
+ return robot.getAngle();
+ }
+
+ @Override
+ public void setAngle(double a) {
+ robot.setAngle(a);
+ }
+
+ @Override
+ public void sparkle() {
+ robot.sparkle();
+ }
+
+ @Override
+ public void unSparkle() {
+ robot.unSparkle();
+ }
+
+ @Override
+ public void hide() {
+ robot.hide();
+ }
+
+ @Override
+ public void show() {
+ robot.show();
+ }
+
+ /**
+ * Draws a regular polygon with center at the robot's current position
+ *
+ * @param numSides the number of sides of the polygon
+ * @param radius the radius of the circumscribed circle.
+ */
+ public void drawPolygon(int numSides, int radius) {
+ int angle = 360 / numSides;
+ double sin = Math.sin(Math.toRadians(angle / 2.0));
+ int sideLen = (int) (2 * radius * Math.abs(sin));
+ penUp();
+ move(radius);
+ turn(90 + angle / 2);
+ penDown();
+ move(sideLen);
+ for (int i = 1; i < numSides; i++) {
+ turn(angle);
+ move(sideLen);
+ }
+ penUp();
+ turn(-90 + angle / 2);
+ }
+
+}
diff --git a/examples/src/Driver.kt b/examples/src/Driver.kt
new file mode 100644
index 0000000..b5b4336
--- /dev/null
+++ b/examples/src/Driver.kt
@@ -0,0 +1,35 @@
+import org.jointheleague.graphical.robot.Robot
+import org.jointheleague.graphical.robot.RobotInterface
+import java.util.*
+
+class DriverKt(private val robot: Robot) : RobotInterface by robot {
+
+ override fun setRandomPenColor() {
+ val shade = 5 * Random().nextInt(50)
+ robot.setPenColor(shade, shade, shade)
+ }
+
+ /**
+ * Draws a regular polygon with center at the robot's current position
+ *
+ * @param numSides the number of sides of the polygon
+ * @param radius the radius of the circumscribed circle.
+ */
+ fun drawPolygon(numSides: Int, radius: Int) {
+ val angle = 360.0 / numSides
+ val sin = Math.sin(Math.toRadians(angle / 2.0))
+ val sideLen = (2.0 * radius.toDouble() * Math.abs(sin)).toInt()
+ penUp()
+ move(radius)
+ turn(90.0 + angle / 2.0)
+ penDown()
+ move(sideLen)
+ for (i in 1 until numSides) {
+ turn(angle)
+ move(sideLen)
+ }
+ penUp()
+ turn(-90.0 + angle / 2.0)
+ }
+
+}
diff --git a/examples/src/ExtendedKeyboardAdapter.java b/examples/src/ExtendedKeyboardAdapter.java
new file mode 100644
index 0000000..50b2246
--- /dev/null
+++ b/examples/src/ExtendedKeyboardAdapter.java
@@ -0,0 +1,34 @@
+import org.jointheleague.graphical.robot.KeyboardAdapter;
+
+import java.awt.event.KeyEvent;
+
+public class ExtendedKeyboardAdapter extends KeyboardAdapter {
+
+
+// public ExtendedKeyboardAdapter() {
+// super();
+// }
+
+
+ @Override
+ public void keyTyped(KeyEvent e) {
+ switch (e.getKeyChar()) {
+ case 'm':
+ robot.miniaturize();
+ break;
+ case 'M':
+ robot.expand();
+ break;
+ case 'u':
+ robot.penUp();
+ break;
+ case 'd':
+ robot.penDown();
+ break;
+ default:
+ super.keyTyped(e);
+ }
+
+ }
+
+}
diff --git a/examples/src/MyRobot.java b/examples/src/MyRobot.java
new file mode 100644
index 0000000..0a5f086
--- /dev/null
+++ b/examples/src/MyRobot.java
@@ -0,0 +1,28 @@
+import org.jointheleague.graphical.robot.Robot;
+
+public class MyRobot extends Robot {
+
+ /**
+ * Draws a regular polygon with center at the robot's current position
+ *
+ * @param numSides the number of sides of the polygon
+ * @param radius the radius of the circumscribed circle.
+ */
+ public void drawPolygon(int numSides, int radius) {
+ int angle = 360 / numSides;
+ double sin = Math.sin(Math.toRadians(angle / 2.0));
+ int sideLen = (int) (2 * radius * Math.abs(sin));
+ penUp();
+ move(radius);
+ turn(90 + angle / 2);
+ penDown();
+ move(sideLen);
+ for (int i = 1; i < numSides; i++) {
+ turn(angle);
+ move(sideLen);
+ }
+ penUp();
+ turn(-90 + angle / 2);
+ }
+
+}
diff --git a/examples/src/RobotExample0.java b/examples/src/RobotExample0.java
new file mode 100644
index 0000000..0ea2a87
--- /dev/null
+++ b/examples/src/RobotExample0.java
@@ -0,0 +1,18 @@
+import org.jointheleague.graphical.robot.Robot;
+
+public class RobotExample0 {
+
+ public static void main(String[] args) {
+
+ Robot rob = new Robot();
+
+ rob.move(200);
+ rob.turn(90);
+ rob.move(200);
+ rob.turn(90);
+ rob.move(200);
+ rob.turn(90);
+ rob.move(200);
+ rob.turn(90);
+ }
+}
\ No newline at end of file
diff --git a/examples/src/RobotExample1.java b/examples/src/RobotExample1.java
new file mode 100644
index 0000000..82630db
--- /dev/null
+++ b/examples/src/RobotExample1.java
@@ -0,0 +1,30 @@
+import org.jointheleague.graphical.robot.Robot;
+
+import java.awt.*;
+
+public class RobotExample1 {
+
+ public static void main(String[] args) {
+
+ Robot rob = new Robot(125, 125);
+
+
+ rob.setSpeed(10);
+ rob.miniaturize();
+ rob.penDown();
+ rob.setPenColor(Color.RED);
+ rob.sleep(1000);
+
+ int[] distances = {260, 150, 260, 150};
+ for (int distance : distances) {
+ rob.turn(90);
+ rob.move(distance);
+ }
+ rob.turn(90);
+ rob.penUp();
+ rob.move(185);
+ rob.turn(-90);
+ rob.setSpeed(2);
+ rob.move(-75);
+ }
+}
\ No newline at end of file
diff --git a/examples/src/RobotExample10.java b/examples/src/RobotExample10.java
new file mode 100644
index 0000000..e064f4f
--- /dev/null
+++ b/examples/src/RobotExample10.java
@@ -0,0 +1,70 @@
+import org.jointheleague.graphical.robot.Robot;
+import org.jointheleague.graphical.robot.RobotWindow;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ThreadLocalRandom;
+
+public class RobotExample10 {
+
+ private static final int NUM_ROBOTS = 10;
+ private int totalDist;
+ private long startTime;
+ private long winnerTime;
+ private CountDownLatch startLatch;
+
+ private void startRace() throws InterruptedException {
+ startLatch = new CountDownLatch(1);
+ for (int i = 0; i < NUM_ROBOTS; i++) {
+ final Robot robot = new Robot(15, 50 * (i + 1));
+ robot.miniaturize();
+ new Thread(getRunnable(robot)).start();
+ }
+ totalDist = RobotWindow.getInstance().getWidth() - 26;
+ Thread.sleep(1000);
+ startLatch.countDown();
+ // Race started!!
+ startTime = System.currentTimeMillis();
+ }
+
+ private Runnable getRunnable(final Robot robot) {
+ return () -> {
+ robot.setSpeed(5);
+ robot.turn(90);
+ int speed = 3;
+ ThreadLocalRandom rng = ThreadLocalRandom.current();
+ try {
+ startLatch.await();
+ } catch (InterruptedException ignore) {
+ }
+ // Race started!!
+ for (int dst = 0; dst < totalDist; dst += 40) {
+ speed += rng.nextInt(3) - 1;
+ speed = Math.min(Math.max(2, speed), 4);
+ robot.setSpeed(speed);
+ robot.move(Math.min(40, totalDist - dst));
+ }
+ // Finish line reached!
+ synchronized (RobotExample10.this) {
+ System.out.println(getTimeResult());
+ }
+ };
+ }
+
+ private String getTimeResult() {
+ final String robotName = Thread.currentThread().getName().replace("Thread", "Robot");
+ long time = System.currentTimeMillis() - startTime - winnerTime;
+ final long seconds = time / 1000;
+ final long millis = time % 1000;
+
+ if (winnerTime == 0L) {
+ winnerTime = time;
+ return String.format("%-9s %2d.%03d", robotName + ":", seconds, millis);
+ } else {
+ return String.format("%-9s +%2d.%03d", robotName + ":", seconds, millis);
+ }
+ }
+
+ public static void main(String... args) throws InterruptedException {
+ new RobotExample10().startRace();
+ }
+}
diff --git a/examples/src/RobotExample11.java b/examples/src/RobotExample11.java
new file mode 100644
index 0000000..dc7909e
--- /dev/null
+++ b/examples/src/RobotExample11.java
@@ -0,0 +1,41 @@
+import org.jointheleague.graphical.robot.Robot;
+
+import java.util.concurrent.CountDownLatch;
+
+public class RobotExample11 {
+
+ private static final int NUM_ROBOTS = 7;
+ private CountDownLatch latch = new CountDownLatch(NUM_ROBOTS);
+
+ public static void main(String[] args) {
+
+ RobotExample11 ex = new RobotExample11();
+ for (int x = 1; x <= NUM_ROBOTS; x++ ) {
+ Robot rob = new Robot(50 * x, 300);
+ rob.setSpeed(20 - x);
+ new Thread(ex.getRunnable(rob)).start();
+ }
+ }
+
+ private Runnable getRunnable(Robot rob) {
+ return () -> {
+ rob.miniaturize();
+ rob.setRandomPenColor();
+ rob.setPenWidth(3);
+ rob.sparkle();
+ rob.sleep(1000);
+
+ rob.penDown();
+ rob.quadTo(350, -300, 500, 0, true);
+ rob.cubicTo(-1000, 300, 200, 300, -500, 0, true);
+ rob.unSparkle();
+ rob.sleep(500);
+ latch.countDown();
+ try {
+ latch.await();
+ } catch (InterruptedException ignore) {
+ }
+ rob.hide();
+ };
+ }
+}
\ No newline at end of file
diff --git a/examples/src/RobotExample12.java b/examples/src/RobotExample12.java
new file mode 100644
index 0000000..34e3ad3
--- /dev/null
+++ b/examples/src/RobotExample12.java
@@ -0,0 +1,28 @@
+import org.jointheleague.graphical.robot.Robot;
+import org.jointheleague.graphical.robot.RobotWindow;
+
+import java.awt.*;
+import java.awt.geom.Ellipse2D;
+
+;
+
+public class RobotExample12 {
+
+ public static void main(String[] args) {
+
+ Robot rob = new Robot();
+ RobotWindow window = RobotWindow.getInstance();
+ int w = window.getWidth();
+ int h = window.getHeight();
+ float d = Math.min(w, h) - 100;
+ Shape ellipse = new Ellipse2D.Float((w - d) / 2F, ( h - d) / 2F, d, d);
+ rob.setSpeed(10);
+ rob.setPenWidth(5);
+ rob.setRandomPenColor();
+ rob.penDown();
+ rob.sleep(500);
+ rob.followPath(ellipse.getPathIterator(null));
+ rob.moveTo(w / 2F, h / 2F, false);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/src/RobotExample13.java b/examples/src/RobotExample13.java
new file mode 100644
index 0000000..e7c3d34
--- /dev/null
+++ b/examples/src/RobotExample13.java
@@ -0,0 +1,49 @@
+import org.jointheleague.graphical.robot.Robot;
+import org.jointheleague.graphical.robot.RobotWindow;
+
+import java.awt.*;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.geom.Rectangle2D;
+
+public class RobotExample13 {
+
+ public static void main(String[] args) {
+
+ char[] text = "Amazing ROBOTS".toCharArray();
+ Robot[] robots = new Robot[text.length];
+ for (int i = 0; i < robots.length; i++) {
+ if (text[i] == ' ') continue;
+ robots[i] = new Robot(100 + 50 * i, 400);
+ robots[i].miniaturize();
+ }
+ RobotWindow window = RobotWindow.getInstance();
+ window.setWinColor(Color.WHITE);
+ final Font font = new Font("Times New Roman", Font.PLAIN, 96);
+// final Font font = new Font("Helvetica", Font.PLAIN, 96);
+ final Graphics2D g2 = (Graphics2D) window.getGraphics();
+ final FontRenderContext frc = g2.getFontRenderContext();
+ final GlyphVector glyphVector =
+ font.layoutGlyphVector(frc, text, 0, text.length, Font.LAYOUT_LEFT_TO_RIGHT);
+ final Rectangle2D textBounds = glyphVector.getLogicalBounds();
+ final Dimension dimension = window.getSize();
+ final float leftMargin = (float) ((dimension.getWidth() - textBounds.getWidth()) / 2);
+ final float topMargin = 100F + (float) ((dimension.getHeight() - textBounds.getHeight()) / 2);
+ for (int i = 0; i < text.length; i++) {
+ if (text[i] == ' ') continue;
+ Shape glyphShape = glyphVector.getGlyphOutline(i, leftMargin, topMargin);
+ Robot rob = robots[i];
+ rob.setSpeed(2);
+ rob.setPenWidth(1);
+ rob.setRandomPenColor();
+ rob.penDown();
+ new Thread(() -> {
+ rob.followPath(glyphShape.getPathIterator(null), true);
+ Rectangle bounds = glyphShape.getBounds();
+ rob.penUp();
+ rob.moveTo(bounds.x + bounds.width / 2F, 400, false);
+ rob.moveTo(0, -1, true);
+ }).start();
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/src/RobotExample14.kt b/examples/src/RobotExample14.kt
new file mode 100644
index 0000000..bac6022
--- /dev/null
+++ b/examples/src/RobotExample14.kt
@@ -0,0 +1,124 @@
+import org.jointheleague.graphical.robot.Robot
+import org.jointheleague.graphical.robot.RobotWindow
+import java.awt.Color
+import java.awt.geom.PathIterator
+import java.io.File
+import java.lang.RuntimeException
+import java.lang.UnsupportedOperationException
+
+private val floatRegex = """[-+]?\d*\.?\d+""".toRegex()
+
+fun getPathIterator(lines: Sequence): PathIterator = object : PathIterator {
+
+ val iterator = lines
+ .filter { !it.isBlank() }
+ .map { it.trim() }
+ .iterator()
+ var done: Boolean = !iterator.hasNext()
+ var currentLine = if (iterator.hasNext()) iterator.next() else ""
+ var refPointX: Float = 0F
+ var refPointY: Float = 0F
+
+ override fun next() {
+ if (iterator.hasNext()) {
+ currentLine = iterator.next()
+ } else {
+ done = true
+ }
+ }
+
+ override fun getWindingRule(): Int = PathIterator.WIND_EVEN_ODD
+
+ override fun currentSegment(coords: FloatArray): Int {
+
+ floatRegex.findAll(currentLine).forEachIndexed { i, matchResult ->
+ coords[i] = matchResult.value.toFloat()
+ }
+
+ return when (currentLine[0]) {
+ 'M', 'm' -> {
+ refPointX = coords[0]
+ refPointY = coords[1]
+ PathIterator.SEG_MOVETO
+ }
+ 'L' -> {
+ refPointX = coords[0]
+ refPointY = coords[1]
+ PathIterator.SEG_LINETO
+ }
+ 'l' -> {
+ for (i in 0..1) {
+ coords[i] += if (i % 2 == 0) refPointX else refPointY
+ }
+ refPointX = coords[0]
+ refPointY = coords[1]
+ PathIterator.SEG_LINETO
+ }
+ 'Q' -> {
+ refPointX = coords[2]
+ refPointY = coords[3]
+ PathIterator.SEG_QUADTO
+ }
+ 'q' -> {
+ for (i in 0..3) {
+ coords[i] += if (i % 2 == 0) refPointX else refPointY
+ }
+ refPointX = coords[2]
+ refPointY = coords[3]
+ PathIterator.SEG_QUADTO
+ }
+ 'C' -> {
+ refPointX = coords[4]
+ refPointY = coords[5]
+ PathIterator.SEG_CUBICTO
+ }
+ 'c' -> {
+ for (i in 0..5) {
+ coords[i] += if (i % 2 == 0) refPointX else refPointY
+ }
+ refPointX = coords[4]
+ refPointY = coords[5]
+ PathIterator.SEG_CUBICTO
+ }
+ 'Z', 'z' -> PathIterator.SEG_CLOSE
+ else -> throw RuntimeException()
+ }
+ }
+
+ override fun currentSegment(coords: DoubleArray): Int {
+ throw UnsupportedOperationException()
+ }
+
+ override fun isDone(): Boolean = done
+}
+
+fun main() {
+
+ val rob = Robot()
+ RobotWindow.getInstance().setWinColor(Color.WHITE)
+ rob.setSpeed(5)
+ rob.penWidth = 1
+ rob.miniaturize()
+ rob.penDown()
+ val rect = sequenceOf(
+ "M100,100",
+ "l300,0",
+ "l0,300",
+ "l-300,0",
+ "Z",
+ "M150,150",
+ "l0,200",
+ "l200,0",
+ "l0,-200",
+ "Z")
+ rob.setPenColor(230, 220, 220)
+ rob.followPath(getPathIterator(rect), true)
+ rob.penColor = Color.DARK_GRAY
+ rob.setSpeed(20)
+ File("examples/res/homer-simpson.txt").useLines {
+ rob.followPath(getPathIterator(it), true)
+ }
+ rob.sleep(1000)
+ rob.hide()
+}
+
diff --git a/examples/src/RobotExample2.java b/examples/src/RobotExample2.java
new file mode 100644
index 0000000..d750bb3
--- /dev/null
+++ b/examples/src/RobotExample2.java
@@ -0,0 +1,12 @@
+import org.jointheleague.graphical.robot.KeyboardAdapter;
+import org.jointheleague.graphical.robot.Robot;
+
+public class RobotExample2 {
+
+ public static void main(String[] args) {
+ Robot rob = new Robot();
+ rob.setSpeed(5);
+ rob.miniaturize();
+ rob.addKeyboardAdapter(new KeyboardAdapter());
+ }
+}
diff --git a/examples/src/RobotExample3.5.java b/examples/src/RobotExample3.5.java
new file mode 100644
index 0000000..0cc7c97
--- /dev/null
+++ b/examples/src/RobotExample3.5.java
@@ -0,0 +1,57 @@
+import org.jointheleague.graphical.robot.Robot;
+import java.awt.Color;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+
+class RegularPolygon extends Robot implements Runnable {
+ private final int numVertices;
+ private final int sideLength;
+
+ private RegularPolygon(int numVertices, int sideLength) {
+ this.numVertices = numVertices;
+ this.sideLength = sideLength;
+ }
+
+ @Override
+ public void run() {
+ System.out.println(Thread.currentThread().getName() + " running...");
+ long start = System.currentTimeMillis();
+ setSpeed(6);
+ penDown();
+ turn(-90);
+ drawPolygon();
+ penUp();
+ System.out.println(Thread.currentThread().getName()+ " done in " + (System.currentTimeMillis() - start) + " ms!");
+ }
+
+ private void drawPolygon() {
+ final int degrees = 360 / numVertices;
+ for (int i = 0; i < numVertices; i++) {
+ move(sideLength);
+ turn(degrees);
+ }
+ }
+
+ public static void main(String... args) throws InterruptedException {
+ Robot.setWindowColor(Color.WHITE);
+
+ RegularPolygon triangle = new RegularPolygon(3, 100);
+ triangle.setPos(200, 300);
+
+ RegularPolygon hexagon = new RegularPolygon(6, 50);
+ hexagon.setPos(450, 300);
+
+ RegularPolygon pentagon = new RegularPolygon(5, 60);
+ pentagon.setPos(700,300);
+
+ Executor executor = Executors.newFixedThreadPool(3);
+ Thread.sleep(1000);
+ for (RegularPolygon robot : new RegularPolygon[]{triangle, hexagon, pentagon}) {
+ robot.miniaturize();
+ executor.execute(robot);
+ }
+ }
+}
+
+
diff --git a/examples/src/RobotExample3.java b/examples/src/RobotExample3.java
new file mode 100644
index 0000000..21010d9
--- /dev/null
+++ b/examples/src/RobotExample3.java
@@ -0,0 +1,14 @@
+import org.jointheleague.graphical.robot.Robot;
+
+public class RobotExample3 {
+
+ public static void main(String[] args) {
+
+ Robot rob = new Robot();
+ String url = "http://icons.iconarchive.com/icons/martin-berube/character/96/Robot-icon.png";
+ rob.changeRobot(url);
+ rob.setSpeed(10);
+ rob.penDown();
+ rob.addKeyboardAdapter(new ExtendedKeyboardAdapter());
+ }
+}
diff --git a/examples/src/RobotExample4.java b/examples/src/RobotExample4.java
new file mode 100644
index 0000000..30951b0
--- /dev/null
+++ b/examples/src/RobotExample4.java
@@ -0,0 +1,41 @@
+import org.jointheleague.graphical.robot.Robot;
+
+import java.awt.*;
+
+public class RobotExample4 {
+ public static void main(String[] args) {
+ Robot rob = new Robot();
+ rob.miniaturize();
+ rob.setSpeed(5);
+ rob.penDown();
+ rob.setPenColor(Color.GRAY);
+ Robot.setWindowColor(Color.WHITE);
+ rob.penUp();
+ rob.move(-10);
+ rob.penDown();
+ rob.move(20);
+ rob.penUp();
+ rob.move(-10);
+ rob.turn(90);
+ rob.move(-10);
+ rob.penDown();
+ rob.move(20);
+ rob.penUp();
+ rob.move(-10);
+ rob.turn(-144);
+ rob.move(123);
+ rob.turn(144);
+ rob.setPenWidth(8);
+ rob.penDown();
+ rob.setSpeed(10);
+ for (int i = 0; i < 10; i++) {
+ rob.setRandomPenColor();
+ rob.move(200);
+ rob.turn(108);
+ }
+ rob.penUp();
+ rob.move(-300);
+ rob.sleep(1000);
+ rob.hide();
+ }
+}
diff --git a/examples/src/RobotExample5.java b/examples/src/RobotExample5.java
new file mode 100644
index 0000000..4bd0e86
--- /dev/null
+++ b/examples/src/RobotExample5.java
@@ -0,0 +1,119 @@
+import org.jointheleague.graphical.robot.Robot;
+
+import java.awt.*;
+
+public class RobotExample5 {
+
+ private static final Object talkingStick = new Object();
+ private Robot vic = new Robot("vic");
+ private Robot june = new Robot("june");
+ private boolean juneDone = false;
+ private boolean vicDone = false;
+ private Runnable vicsPart = () -> {
+ vic.setPos(300, 300);
+ firstMovement(vic);
+ vicIsDone();
+ waitForJune();
+ secondMovement(vic);
+ waitForJune();
+ vic.setSpeed(5);
+ vic.move(-200);
+ vic.hide();
+ };
+ private Runnable junesPart = () -> {
+ june.setPos(600, 300);
+ waitForVic();
+ firstMovement(june);
+ june.sleep(500);
+ juneIsDone();
+ secondMovement(june);
+ june.turn(180);
+ june.sleep(500);
+ juneIsDone();
+ june.setSpeed(5);
+ june.move(200);
+ june.hide();
+ };
+
+ public static void main(String[] args) {
+ new RobotExample5().play();
+ }
+
+ private void play() {
+ Robot.setWindowColor(Color.WHITE);
+ new Thread(vicsPart).start();
+ new Thread(junesPart).start();
+ }
+
+ private void firstMovement(Robot robot) {
+ robot.setSpeed(2);
+ robot.setPenColor(Color.GRAY);
+ robot.penUp();
+ robot.move(-10);
+ robot.penDown();
+ robot.move(20);
+ robot.penUp();
+ robot.move(-10);
+ robot.turn(90);
+ robot.move(-10);
+ robot.penDown();
+ robot.move(20);
+ robot.penUp();
+ robot.move(-10);
+ robot.setSpeed(10);
+ robot.turn(-144);
+ robot.move(123);
+ robot.turn(144);
+ }
+
+ private void secondMovement(Robot robot) {
+ robot.setPenWidth(8);
+ robot.penDown();
+ for (int i = 0; i < 10; i++) {
+ robot.setRandomPenColor();
+ robot.move(200);
+ robot.turn(108);
+ }
+ robot.penUp();
+ }
+
+ private void waitForJune() {
+ synchronized (talkingStick) {
+ juneDone = false;
+ try {
+ while (!juneDone) {
+ talkingStick.wait();
+ }
+ } catch (InterruptedException e) {
+ assert false; // No interrupts expected
+ }
+ }
+ }
+
+ private void juneIsDone() {
+ synchronized (talkingStick) {
+ juneDone = true;
+ talkingStick.notify();
+ }
+ }
+
+ private void waitForVic() {
+ synchronized (talkingStick) {
+ vicDone = false;
+ try {
+ while (!vicDone) {
+ talkingStick.wait();
+ }
+ } catch (InterruptedException e) {
+ assert false; // No interrupts expected
+ }
+ }
+ }
+
+ private void vicIsDone() {
+ synchronized (talkingStick) {
+ vicDone = true;
+ talkingStick.notify();
+ }
+ }
+}
diff --git a/examples/src/RobotExample6.java b/examples/src/RobotExample6.java
new file mode 100644
index 0000000..f7b24be
--- /dev/null
+++ b/examples/src/RobotExample6.java
@@ -0,0 +1,13 @@
+import org.jointheleague.graphical.robot.Robot;
+
+public class RobotExample6 {
+
+ public static void main(String[] args) throws InterruptedException {
+ Robot vic = new Robot("vic", 600, 300);
+ Robot june = new Robot("june", 300, 300);
+ june.setSpeed(10);
+ vic.setSpeed(10);
+ vic.addKeyboardAdapter(new ShiftKeyboardAdapter(true));
+ june.addKeyboardAdapter(new ShiftKeyboardAdapter(false));
+ }
+}
diff --git a/examples/src/RobotExample8.java b/examples/src/RobotExample8.java
new file mode 100644
index 0000000..4355eaf
--- /dev/null
+++ b/examples/src/RobotExample8.java
@@ -0,0 +1,17 @@
+// No imports
+
+public class RobotExample8 {
+
+ public static void main(String[] args) {
+ MyRobot rob = new MyRobot();
+ rob.setSpeed(10);
+ rob.turn(45);
+ rob.penDown();
+ for (int i : new int[]{3, 4, 5, 6, 8, 10}) {
+ rob.setPos(450, 300);
+ rob.setRandomPenColor();
+ rob.drawPolygon(i, 200);
+ }
+ rob.hide();
+ }
+}
diff --git a/examples/src/RobotExample9.java b/examples/src/RobotExample9.java
new file mode 100644
index 0000000..2d51151
--- /dev/null
+++ b/examples/src/RobotExample9.java
@@ -0,0 +1,17 @@
+import org.jointheleague.graphical.robot.Robot;
+
+public class RobotExample9 {
+
+ public static void main(String[] args) {
+ Driver rob = new Driver(new Robot());
+ rob.setSpeed(10);
+ rob.turn(45);
+ rob.penDown();
+ for (int i : new int[]{3, 4, 5, 6, 8, 10}) {
+ rob.setPos(450, 300);
+ rob.setRandomPenColor();
+ rob.drawPolygon(i, 200);
+ }
+ rob.hide();
+ }
+}
diff --git a/examples/src/RobotExample9bis.java b/examples/src/RobotExample9bis.java
new file mode 100644
index 0000000..6cf4d58
--- /dev/null
+++ b/examples/src/RobotExample9bis.java
@@ -0,0 +1,17 @@
+import org.jointheleague.graphical.robot.Robot;
+
+public class RobotExample9bis {
+
+ public static void main(String[] args) {
+ DriverKt rob = new DriverKt(new Robot());
+ rob.setSpeed(10);
+ rob.turn(45);
+ rob.penDown();
+ for (int i : new int[]{3, 4, 5, 6, 8, 10}) {
+ rob.setPos(450, 300);
+ rob.setRandomPenColor();
+ rob.drawPolygon(i, 200);
+ }
+ rob.hide();
+ }
+}
diff --git a/examples/src/ShiftKeyboardAdapter.java b/examples/src/ShiftKeyboardAdapter.java
new file mode 100644
index 0000000..f64d6cb
--- /dev/null
+++ b/examples/src/ShiftKeyboardAdapter.java
@@ -0,0 +1,35 @@
+import org.jointheleague.graphical.robot.KeyboardAdapter;
+
+import java.awt.event.KeyEvent;
+
+public class ShiftKeyboardAdapter extends KeyboardAdapter {
+
+ private final boolean shiftDown;
+
+ /**
+ * Constructor.
+ *
+ * @param shiftDown if true, the Shift key needs to be depressed to react to arrow
+ * keys; if false, the Shift key must not be depressed to react
+ * to arrow keys.
+ */
+ public ShiftKeyboardAdapter(boolean shiftDown) {
+ super();
+ this.shiftDown = shiftDown;
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ if (e.isShiftDown() == shiftDown) {
+ super.keyPressed(e);
+ }
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ if (e.isShiftDown() == shiftDown) {
+ super.keyReleased(e);
+ }
+ }
+
+}
diff --git a/examples/test/RobotExample14KtTest.kt b/examples/test/RobotExample14KtTest.kt
new file mode 100644
index 0000000..156f7c1
--- /dev/null
+++ b/examples/test/RobotExample14KtTest.kt
@@ -0,0 +1,63 @@
+import org.junit.jupiter.api.Test
+import java.awt.geom.PathIterator
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+
+class RobotExample14KtTest {
+
+ @Test
+ fun testGetPathIterator() {
+ val input = sequenceOf(
+ "",
+ " M 1.2 3.2",
+ " ",
+ "L4-5.6",
+ "C7.910,11.2 3,4,5.6 7.8 ",
+ " c -3.4-5.6, 7 8,9.1 11.2",
+ "\t\n ",
+ "Z",
+ " ",
+ "")
+ val pathIterator = getPathIterator(input)
+ val coords = FloatArray(6)
+ // First segment -- " M 1.2 3.2"
+ assertFalse(pathIterator.isDone)
+ assertEquals(PathIterator.SEG_MOVETO, pathIterator.currentSegment(coords))
+ assertEquals(1.2F, coords[0])
+ assertEquals(3.2F, coords[1])
+ // Second segment -- "L4-5.6"
+ pathIterator.next()
+ assertFalse(pathIterator.isDone)
+ assertEquals(PathIterator.SEG_LINETO, pathIterator.currentSegment(coords))
+ assertEquals(4F, coords[0])
+ assertEquals(- 5.6F, coords[1])
+ // Third segment -- "C7.910,11.2 3,4,5.6 7.8 "
+ pathIterator.next()
+ assertFalse(pathIterator.isDone)
+ assertEquals(PathIterator.SEG_CUBICTO, pathIterator.currentSegment(coords))
+ assertEquals(7.91F, coords[0])
+ assertEquals(11.2F, coords[1])
+ assertEquals(3F, coords[2])
+ assertEquals(4F, coords[3])
+ assertEquals(5.6F, coords[4])
+ assertEquals(7.8F, coords[5])
+ // Fourth segment -- " c -3.4-5.6, 7 8,9.1 11.2"
+ pathIterator.next()
+ assertFalse(pathIterator.isDone)
+ assertEquals(PathIterator.SEG_CUBICTO, pathIterator.currentSegment(coords))
+ assertEquals(5.6F - 3.4F, coords[0])
+ assertEquals(7.8F - 5.6F, coords[1])
+ assertEquals(5.6F + 7F, coords[2])
+ assertEquals(7.8F + 8F, coords[3])
+ assertEquals(5.6F + 9.1F, coords[4])
+ assertEquals(7.8F + 11.2F, coords[5])
+ // Fifth segment -- "Z"
+ pathIterator.next()
+ assertFalse(pathIterator.isDone)
+ assertEquals(PathIterator.SEG_CLOSE, pathIterator.currentSegment(coords))
+ // End of pathIterator
+ pathIterator.next()
+ assertTrue(pathIterator.isDone)
+ }
+}
\ No newline at end of file
diff --git a/jar/Robot.jar b/jar/Robot.jar
deleted file mode 100644
index 3598902..0000000
Binary files a/jar/Robot.jar and /dev/null differ
diff --git a/jar/robot.jar b/jar/robot.jar
new file mode 100644
index 0000000..f4e43f1
Binary files /dev/null and b/jar/robot.jar differ
diff --git a/src/org/jointheleague/graphical/robot/KeyboardAdapter.java b/src/org/jointheleague/graphical/robot/KeyboardAdapter.java
new file mode 100644
index 0000000..ab427bc
--- /dev/null
+++ b/src/org/jointheleague/graphical/robot/KeyboardAdapter.java
@@ -0,0 +1,193 @@
+package org.jointheleague.graphical.robot;
+
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+
+/**
+ *
+ * This class is used to control a robot through key presses. The up, down,
+ * left, and right arrow keys are used to make the robot advance, go backwards,
+ * turn left, and turn right respectively. The {@link KeyEvent}s that are used
+ * to control the Robot and the ways that those KeyEvents control the Robot can
+ * be changed by extending this class and overriding the
+ * {@link #keyPressed(KeyEvent)}, {@link #keyReleased(KeyEvent)}, and
+ * {@link #keyTyped(KeyEvent)} methods.
+ *
+ *
+ * It is possible to add multiple KeyboardAdapters each controlling a different
+ * Robot. To be able to distinguish which {@link KeyEvent}s control which
+ * Robots, the set of KeyEvents that each KeyboardAdapter reacts to should be
+ * distinct. For example, one KeyboardAdapter could react only to KeyEvents
+ * where the Shift key is not depressed, and another could react only to events
+ * where the Shift key is depressed. It is, nevertheless, also possible to have
+ * all KeyboardAdapters react to a same KeyEvent. For example, when the user
+ * types 'm', each KeyboardAdapter could react by miniaturizing the Robot that
+ * it controls.
+ *
+ *
+ * A KeyboardAdapter controls the Robot from its own thread. It is not possible
+ * to have more than one KeyboardAdapter controlling the same Robot.
+ *
+ *
+ * Example of how to use:
+ *
+ *
+ *
+ * {@code
+ * public static void main(String[] args) throws InterruptedException
+ * {
+ * Robot rob = new Robot();
+ * rob.addKeyboardAdapter(new KeyboardAdapter());
+ * }
+ * }
+ *
+ *
+ *
+ * @author Erik Colban © 2016
+ *
+ */
+public class KeyboardAdapter implements KeyListener, Runnable {
+
+ /**
+ * The Robot instance that the KeyboardAdapter is attached to.
+ */
+ protected Robot robot;
+ private volatile boolean movingForward = false;
+ private volatile boolean movingBackward = false;
+ private volatile boolean turningLeft = false;
+ private volatile boolean turningRight = false;
+
+ /**
+ * Constructor.
+ */
+ public KeyboardAdapter() {
+ }
+
+ public void setRobot(Robot robot) {
+ this.robot = robot;
+ new Thread(this).start();
+ }
+
+ @Override
+ public void run() {
+ while (!Thread.currentThread().isInterrupted()) {
+
+ try {
+ if (movingForward && !movingBackward) {
+ robot.microMove(1);
+ } else if (movingBackward && !movingForward) {
+ robot.microMove(-1);
+ } else if (turningRight && !turningLeft) {
+ robot.microTurn(1);
+ } else if (turningLeft && !turningRight) {
+ robot.microTurn(-1);
+ } else {
+ robot.doNothing();
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ System.out.println(e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * Sets or unsets the Robot in a forward motion.
+ *
+ * @param movingForward
+ * true to set the Robot in forward motion, false to cancel
+ * forward motion.
+ */
+ protected void setMovingForward(boolean movingForward) {
+ this.movingForward = movingForward;
+ }
+
+ /**
+ * Sets or unsets the Robot in a backward motion.
+ *
+ * @param movingBackward
+ * true to set the Robot in backward motion, false to cancel
+ * backward motion.
+ */
+ protected void setMovingBackward(boolean movingBackward) {
+ this.movingBackward = movingBackward;
+ }
+
+ /**
+ * Sets or unsets the Robot in a left turning motion.
+ *
+ * @param turningLeft
+ * true to set the Robot in a left turning motion, false to
+ * cancel the turning motion.
+ */
+ protected void setTurningLeft(boolean turningLeft) {
+ this.turningLeft = turningLeft;
+ }
+
+ /**
+ * Sets or unsets the Robot in a left turning motion.
+ *
+ * @param turningRight
+ * true to set the Robot in a right turning motion, false to
+ * cancel the turning motion.
+ */
+ protected void setTurningRight(boolean turningRight) {
+ this.turningRight = turningRight;
+ }
+
+ /**
+ * No actions are specified, but that can be overridden in extensions of
+ * this class.
+ */
+ @Override
+ public void keyTyped(KeyEvent e) {
+ }
+
+ /**
+ * Implements the natural movements associated with the up, down, left, and
+ * right arrow keys.
+ */
+ @Override
+ public void keyPressed(KeyEvent e) {
+ switch (e.getKeyCode()) {
+ case KeyEvent.VK_UP:
+ movingForward = true;
+ break;
+ case KeyEvent.VK_DOWN:
+ movingBackward = true;
+ break;
+ case KeyEvent.VK_LEFT:
+ turningLeft = true;
+ break;
+ case KeyEvent.VK_RIGHT:
+ turningRight = true;
+ break;
+ default:
+ }
+
+ }
+
+ /**
+ * Implements the natural movements associated with the up, down, left, and
+ * right arrow keys.
+ */
+ @Override
+ public void keyReleased(KeyEvent e) {
+ switch (e.getKeyCode()) {
+ case KeyEvent.VK_UP:
+ movingForward = false;
+ break;
+ case KeyEvent.VK_DOWN:
+ movingBackward = false;
+ break;
+ case KeyEvent.VK_LEFT:
+ turningLeft = false;
+ break;
+ case KeyEvent.VK_RIGHT:
+ turningRight = false;
+ break;
+ default:
+ }
+ }
+
+}
diff --git a/src/org/jointheleague/graphical/robot/Line.java b/src/org/jointheleague/graphical/robot/Line.java
deleted file mode 100644
index 1a1bcea..0000000
--- a/src/org/jointheleague/graphical/robot/Line.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.jointheleague.graphical.robot;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Stroke;
-
-public class Line {
-
-
- private int startX;
- private int startY;
- private int endX;
- private int endY;
-
- private int lineSize;
-
- private Color color;
-
- public Line(int sx, int sy, int tx, int ty, int size, Color c)
- {
- startX = sx;
- startY = sy;
- endX = tx;
- endY = ty;
- lineSize = size + 1;
-
- color = c;
- }
-
- public void draw(Graphics g)
- {
- Graphics2D g2 = (Graphics2D)g;
- Stroke s = g2.getStroke();
-
- g2.setStroke(new BasicStroke(lineSize));
- g.setColor(color);
- g.drawLine(startX, startY, endX, endY);
- g2.setStroke(s);
- }
-}
diff --git a/src/org/jointheleague/graphical/robot/Pixel.java b/src/org/jointheleague/graphical/robot/Pixel.java
deleted file mode 100644
index 28bbc82..0000000
--- a/src/org/jointheleague/graphical/robot/Pixel.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.jointheleague.graphical.robot;
-import java.awt.Color;
-
-public class Pixel extends Vector2D {
- private Color color;
-
- public Pixel()
- {
- this(0, 0);
- }
-
- public Pixel(int x, int y)
- {
- super(x, y);
- color = Color.GREEN;
- }
-
- public Pixel(int x, int y, Color c)
- {
- super(x, y);
- color = c;
- }
-
- public Color getColor()
- {
- return color;
- }
-
-}
diff --git a/src/org/jointheleague/graphical/robot/Robot.java b/src/org/jointheleague/graphical/robot/Robot.java
index c8c3b1c..25e617e 100644
--- a/src/org/jointheleague/graphical/robot/Robot.java
+++ b/src/org/jointheleague/graphical/robot/Robot.java
@@ -1,481 +1,657 @@
package org.jointheleague.graphical.robot;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
+import org.jointheleague.graphical.robot.curves.*;
+
+import javax.imageio.ImageIO;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyListener;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.net.URL;
import java.util.ArrayList;
+import java.util.List;
import java.util.Random;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ThreadLocalRandom;
+
+/**
+ *
+ * This class is used to show a robot inside a window. If no RobotWindow exists
+ * when instantiating a Robot, a window is created and the Robot placed inside
+ * the window. If a RobotWindow already exists, the new Robot is placed inside
+ * the existing RobotWindow.
+ *
+ *
+ * A Robot is controlled by calling its {@link #move(int)}, {@link #turn(double)},
+ * {@link #microMove(int)}, and {@link #microTurn(int)} methods. These methods
+ * should be called from the same thread, which is typically the main thread,
+ * but different Robots may be controlled from different threads, thereby
+ * allowing the Robots to move simultaneously.
+ *
+ *
+ * A Robot also has state, e.g., visible or hidden, pen size, pen up or down,
+ * etc. This state may be modified by calling the respective setter methods.
+ *
+ *
+ * @author David Dunn & Erik Colban © 2016
+ */
+public class Robot implements RobotInterface {
+
+ static final int TICK_LENGTH = 20; // in milliseconds
+ private static final int MAXI_IMAGE_SIZE = 100;
+ private static final int MINI_IMAGE_SIZE = 25;
+ private static final int MIN_SPEED = 1;
+ private static final int MAX_SPEED = 100;
+
+ // Robot state start
+ private int speed;
+ private boolean penDown;
+ private int penWidth;
+ private Color penColor;
+ private Pos pos;
+ private double angle;
+ private boolean isVisible;
+ private boolean isSparkling;
+ private ArrayList drawables;
+ private Drawable currentDrawable;
+ private boolean isMini;
+ private Image maxiImage;
+ private Image miniImage;
+ private Image image;
+ // Robot state end
+
+ private RobotWindow window;
+ private BlockingQueue leakyBucket = new ArrayBlockingQueue<>(1);
+ private DynamicPath currentPath;
+
+ public Robot() {
+ this("rob");
+ }
+
+ /**
+ * Instantiates a new default Robot at the position provided.
+ *
+ * @param xPos the x-coordinate of the Robot's center
+ * @param yPos the y-coordinate of the Robot's center
+ */
+ public Robot(int xPos, int yPos) {
+ this("rob", xPos, yPos);
+ }
+
+ /**
+ * Instantiates a new Robot whose image is specified by the filename at the
+ * center of the RobotWindow.
+ *
+ * @param fileName The file name without extension of a file in robi format that
+ * specifies the Robot's image.
+ */
+ public Robot(String fileName) {
+ this(RobotImage.loadRobi(fileName));
+ }
+
+ /**
+ * Instantiates a new Robot at the center of the RobotWindow.
+ *
+ * @param robotImage a BufferedImage containing the robot image. It does not need
+ * to be to scale since it will be scaled to the appropriate
+ * size.
+ */
+ public Robot(BufferedImage robotImage) {
+ this(robotImage, 0, 0);
+ Dimension dimension = window.getSize();
+ setPos(dimension.width / 2F, dimension.height / 2F);
+ }
+
+ /**
+ * @param fileName the name of the file containing the Robot image, without the
+ * ".robi" extension.
+ * @param xPos the initial x-coordinate of the robot
+ * @param yPos the initial y-coordinate of the robot
+ */
+ public Robot(String fileName, int xPos, int yPos) {
+ this(RobotImage.loadRobi(fileName), xPos, yPos);
+ }
+
+ /**
+ * @param inputImage a BufferedImage containing the robot image. It does not need
+ * to be to scale since it will be scaled to the appropriate
+ * size.
+ * @param xPos the initial x-coordinate of the robot
+ * @param yPos the initial y-coordinate of the robot
+ */
+ public Robot(BufferedImage inputImage, int xPos, int yPos) {
+ angle = 0;
+ speed = 1;
+ this.pos = new Pos(xPos, yPos);
+ penWidth = 1;
+ penColor = Color.BLACK;
+
+ isVisible = true;
+ penDown = false;
+ isSparkling = false;
+
+ maxiImage = inputImage.getScaledInstance(MAXI_IMAGE_SIZE, MAXI_IMAGE_SIZE, Image.SCALE_SMOOTH);
+ miniImage = inputImage.getScaledInstance(MINI_IMAGE_SIZE, MINI_IMAGE_SIZE, Image.SCALE_SMOOTH);
+ image = maxiImage;
+ isMini = false;
+
+ drawables = new ArrayList<>();
+ window = RobotWindow.getInstance();
+ window.addRobot(this);
+ }
+
+ /**
+ * Sets the window's background color
+ *
+ * @param color the new window background color.
+ */
+ public static void setWindowColor(final Color color) {
+ SwingUtilities.invokeLater(() -> RobotWindow.getInstance().setWinColor(color));
+ }
+
+ /**
+ * Sets the window's background image
+ *
+ * @param imageLocation the new window background image location.
+ */
+ public static void setWindowImage(final String imageLocation) {
+ SwingUtilities.invokeLater(() -> RobotWindow.getInstance().setBackgroundImage(imageLocation));
+ }
+
+ /**
+ * Sets the window size
+ *
+ * @param width the width of the window
+ * @param height the height of the window
+ */
+ public static void setWindowSize(int width, int height) {
+ SwingUtilities.invokeLater(() -> RobotWindow.getInstance().setWindowSize(width, height));
+ }
+
+ /**
+ * Sets the window's background color given the red, green and blue
+ * components of the new color. The components are specified as an integer
+ * between 0 and 255.
+ *
+ * @param r the red component of the new color
+ * @param g the green component of the new color
+ * @param b the blue component of the new color
+ */
+ public static void setWindowColor(int r, int g, int b) {
+ r = Math.min(Math.max(0, r), 255);
+ g = Math.min(Math.max(0, g), 255);
+ b = Math.min(Math.max(0, b), 255);
+
+ Robot.setWindowColor(new Color(r, g, b));
+ }
+
+ /**
+ * Draws the Robot
+ *
+ * @param g2 The graphics object used to draw the Robot.
+ */
+ void draw(Graphics2D g2) {
+ for (Drawable drawable : getDrawables()) {
+ drawable.draw(g2);
+ }
+ // draws under robot
+ if (isPenDown()) {
+ Drawable drawable = getCurrentDrawable();
+ if (drawable != null) drawable.draw(g2);
+ }
+
+ // first cache the standard coordinate system
+ AffineTransform cached = g2.getTransform();
+ // align the coordinate system with the center of the robot:
+ g2.translate(pos.x, pos.y);
+ g2.rotate(Math.toRadians(getAngle()));
+
+ if (isVisible()) {
+ int offset = -(isMini() ? MINI_IMAGE_SIZE : MAXI_IMAGE_SIZE) / 2;
+ g2.drawImage(image, offset, offset, null);
+ }
+
+ if (penDown && isVisible) // draws over robot
+ {
+ g2.setColor(Color.RED);
+ if (isMini()) {
+ g2.fillOval(-2, -2, 4, 4);
+ } else {
+ g2.fillOval(-4, -4, 8, 8);
+ }
+ }
+
+ if (isVisible() && isSparkling()) {
+ if (isMini()) {
+ double s = (double) MINI_IMAGE_SIZE / MAXI_IMAGE_SIZE;
+ g2.scale(s, s);
+ }
+ Random r = new Random();
+ int xDot = r.nextInt(MAXI_IMAGE_SIZE - 4) - MAXI_IMAGE_SIZE / 2;
+ int yDot = r.nextInt(MAXI_IMAGE_SIZE - 4) - MAXI_IMAGE_SIZE / 2;
+ g2.setColor(Color.WHITE);
+ g2.fillRect(xDot, yDot, 5, 5);
+ }
+ g2.setTransform(cached); // restore the standard coordinate system
+ }
+
+ private synchronized boolean isMini() {
+ return isMini;
+ }
+
+ @Override
+ public synchronized void changeRobot(BufferedImage im) {
+ Image imMax = im.getScaledInstance(MAXI_IMAGE_SIZE, MAXI_IMAGE_SIZE, Image.SCALE_SMOOTH);
+ Image imMin = im.getScaledInstance(MINI_IMAGE_SIZE, MINI_IMAGE_SIZE, Image.SCALE_SMOOTH);
+ synchronized (this) {
+ maxiImage = imMax;
+ miniImage = imMin;
+ image = isMini ? miniImage : maxiImage;
+ }
+ }
+
+ @Override
+ public synchronized void changeRobot(String urlName) {
+ BufferedImage newImage;
+ try {
+ URL url = new URL(urlName);
+ newImage = ImageIO.read(url);
+ } catch (IOException e) {
+ System.err.println("There was an error changing robot's image. Make sure the URL addresses an image.");
+ e.printStackTrace();
+ newImage = (BufferedImage) image;
+ }
+ changeRobot(newImage);
+ }
+
+ @Override
+ public int getPenWidth() {
+ return penWidth;
+ }
+
+ @Override
+ public synchronized void setPenWidth(int size) {
+ penWidth = Math.min(Math.max(1, size), 10);
+ }
+
+ @Override
+ public synchronized Color getPenColor() {
+ return penColor;
+ }
+
+ @Override
+ public synchronized void setPenColor(Color color) {
+ penColor = color;
+ }
+
+ @Override
+ public void setPenColor(int r, int g, int b) {
+ r = Math.min(Math.max(0, r), 255);
+ g = Math.min(Math.max(0, g), 255);
+ b = Math.min(Math.max(0, b), 255);
+
+ penColor = new Color(r, g, b);
+ }
+
+ @Override
+ public void setRandomPenColor() {
+ ThreadLocalRandom rng = ThreadLocalRandom.current();
+ int r = rng.nextInt(256);
+ int b = rng.nextInt(256);
+ int g = rng.nextInt(256);
+ penColor = new Color(r, g, b);
+ }
+
+ private synchronized void addDrawable(final Drawable segment) {
+ drawables.add(segment);
+ }
+
+ @Override
+ public synchronized void clearDrawables() {
+ drawables.clear();
+ }
+
+ private synchronized List getDrawables() {
+ return new ArrayList<>(drawables);
+ }
+
+ private synchronized Drawable getCurrentDrawable() {
+ return currentDrawable;
+ }
+
+ private synchronized void setCurrentDrawable(Drawable drawable) {
+ this.currentDrawable = drawable;
+ }
+
+ @Override
+ public synchronized void miniaturize() {
+ image = miniImage;
+ isMini = true;
+ }
+
+ @Override
+ public synchronized void expand() {
+ image = maxiImage;
+ isMini = false;
+ }
+
+ @Override
+ public synchronized void setPos(float x, float y) {
+ pos = new Robot.Pos(x, y);
+ }
+
+ @Override
+ public synchronized double getAngle() {
+ return angle;
+ }
+
+ @Override
+ public synchronized void setAngle(double a) {
+ angle = (a + 180.0) % 360.0 - 180.0;
+ if (angle < -180) angle += 360;
+ }
+
+ private synchronized void incrementAngle(int delta) {
+ setAngle(angle + delta);
+ }
+
+ private synchronized boolean isSparkling() {
+ return isSparkling;
+ }
+
+ @Override
+ public synchronized void sparkle() {
+ isSparkling = true;
+ }
+
+ @Override
+ public synchronized void unSparkle() {
+ isSparkling = false;
+ }
+
+ private synchronized boolean isVisible() {
+ return isVisible;
+ }
+
+ @Override
+ public synchronized void hide() {
+ isVisible = false;
+ }
+
+ @Override
+ public synchronized void show() {
+ isVisible = true;
+ }
+
+ @Override
+ public void move(int distance) {
+ float[] ctrlPoints = new float[2];
+
+ final double rAngle = Math.toRadians(getAngle());
+ ctrlPoints[0] = (float) (getX() + distance * Math.sin(rAngle));
+ ctrlPoints[1] = (float) (getY() - distance * Math.cos(rAngle));
+ segmentTo(new Line(getX(), getY(), ctrlPoints, getPenWidth(), getPenColor()), distance >= 0);
+ }
+
+ @Override
+ public void microMove(int sgn) throws InterruptedException {
+ if (sgn == 0) {
+ throw new IllegalArgumentException("The argument sgn must be non-zero.");
+ }
+ final float distance = (sgn < 0 ? -1 : 1) * speed;
+ final double rAngle = Math.toRadians(getAngle());
+ final float startX = getX();
+ final float startY = getY();
+ final float endX = (float) (getX() + distance * Math.sin(rAngle));
+ final float endY = (float) (getY() - distance * Math.cos(rAngle));
+ leakyBucket.take();
+ pos = new Pos(endX, endY);
+ if (isPenDown()) {
+ final float[] ctrlPoints = new float[]{endX, endY};
+ synchronized (this) {
+ addDrawable(new Line(startX, startY, ctrlPoints, getPenWidth(), getPenColor()));
+ }
+ }
+ }
+
+ @Override
+ public void turn(double degrees) {
+ double degreesTurned = 0;
+ int sgn = degrees < 0 ? -1 : 1;
+
+ double angle0 = getAngle();
+ try {
+ while (sgn * (degreesTurned - degrees) < 0) {
+ leakyBucket.take(); // will block until a TimeQuatum.TICK becomes available
+ degreesTurned += sgn * speed;
+ if (sgn * (degreesTurned - degrees) > 0) {
+ degreesTurned = degrees;
+ }
+ setAngle(angle0 + degreesTurned);
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void turnTo(double degrees) {
+ turn(getAngleToTurn(degrees));
+ }
+
+ @Override
+ public void microTurn(int sgn) throws InterruptedException {
+ if (sgn == 0) {
+ throw new IllegalArgumentException("sgn must be non-zero.");
+ }
+ leakyBucket.take();
+ incrementAngle(sgn * speed);
+ }
+
+ void doNothing() {
+ try {
+ leakyBucket.take();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void sleep(int millis) {
+ try {
+ int numTicks = millis / TICK_LENGTH;
+ for (int i = 0; i < numTicks; i++) {
+ leakyBucket.take();
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ @Deprecated
+ public synchronized void moveTo(float x, float y) {
+ pos = new Pos(x, y);
+ }
+
+ @Override
+ public void moveTo(float x, float y, boolean relative) {
+ float[] ctrlPoints = new float[2];
+ ctrlPoints[0] = relative ? getX() + x : x;
+ ctrlPoints[1] = relative ? getY() + y : y;
+ segmentTo(new Move(getX(), getY(), ctrlPoints), true);
+ }
+
+ @Override
+ public void lineTo(final float x, final float y, final boolean relative) {
+ float[] ctrlPoints = new float[2];
+ ctrlPoints[0] = relative ? getX() + x : x;
+ ctrlPoints[1] = relative ? getY() + y : y;
+ segmentTo(new Line(getX(), getY(), ctrlPoints, getPenWidth(), getPenColor()), true);
+ }
+
+ @Override
+ public void quadTo(float x1, float y1, float x2, float y2, boolean relative) {
+ float[] ctrlPoints = new float[4];
+ ctrlPoints[0] = relative ? getX() + x1 : x1;
+ ctrlPoints[1] = relative ? getY() + y1 : y1;
+ ctrlPoints[2] = relative ? getX() + x2 : x2;
+ ctrlPoints[3] = relative ? getY() + y2 : y2;
+ segmentTo(new Quad(getX(), getY(), ctrlPoints, getPenWidth(), getPenColor()), true);
+ }
+
+ @Override
+ public void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3, boolean relative) {
+ float[] ctrlPoints = new float[6];
+ ctrlPoints[0] = relative ? getX() + x1 : x1;
+ ctrlPoints[1] = relative ? getY() + y1 : y1;
+ ctrlPoints[2] = relative ? getX() + x2 : x2;
+ ctrlPoints[3] = relative ? getY() + y2 : y2;
+ ctrlPoints[4] = relative ? getX() + x3 : x3;
+ ctrlPoints[5] = relative ? getY() + y3 : y3;
+ segmentTo(new Cubic(getX(), getY(), ctrlPoints, getPenWidth(), getPenColor()), true);
+ }
+
+ private void segmentTo(Segment segment, boolean forwards) {
+ final double directionAdjustment = forwards ? 0.0 : Math.PI;
+ double startAngle = segment.getStartAngle();
+ if (!Double.isNaN(startAngle)) turnTo(startAngle + directionAdjustment);
+
+ final float deltaT = speed / segment.getSize();
+ float t = 0.0F;
+ try {
+ while (t < 1.0F) {
+ leakyBucket.take();
+ t += deltaT;
+ Segment subSegment = segment.subSegment(t);
+ pos = subSegment.getPos(1F);
+ double endAngle = subSegment.getEndAngle();
+ if (!Double.isNaN(endAngle)) setAngle(Math.toDegrees(endAngle + directionAdjustment));
+ if (isPenDown() && (subSegment instanceof Drawable)) {
+ setCurrentDrawable((Drawable) subSegment);
+ }
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ synchronized (this) {
+ if (currentDrawable != null) {
+ addDrawable(currentDrawable);
+ setCurrentDrawable(null);
+ }
+ }
+ }
+
+ @Override
+ public void followPath(PathIterator pathIterator, boolean fill) {
+ DynamicPath dynamicPath = new DynamicPath(pathIterator, getPenWidth(), getPenColor(), this, fill);
+ if (isPenDown()) currentDrawable = dynamicPath;
+ try {
+ while (!dynamicPath.isComplete()) {
+ leakyBucket.take();
+ dynamicPath.incrementTime(speed);
+ }
+ } catch (InterruptedException ignore) {
+ }
+ synchronized (this) {
+ if (currentDrawable != null) {
+ addDrawable(currentDrawable);
+ setCurrentDrawable(null);
+ }
+ }
+ }
+
+ @Override
+ public void followPath(PathIterator pathIterator) {
+ followPath(pathIterator, false);
+ }
+
+ private double getAngleToTurn(final double targetAngle) {
+ final double angle = Math.toDegrees(targetAngle - Math.toRadians(getAngle()));
+ if (angle > 180.0) return (angle + 180.0) % 360.0 - 180.0;
+ if (angle < -180.0) return (angle - 180.0) % 360.0 + 180.0;
+ return angle;
+ }
+
+ @Override
+ public synchronized float getX() {
+ return pos.x;
+ }
+
+ @Override
+ public synchronized float getY() {
+ return pos.y;
+ }
+
+ private synchronized boolean isPenDown() {
+ return penDown;
+ }
+
+ @Override
+ public synchronized void penUp() {
+ penDown = false;
+ }
+
+ @Override
+ public synchronized void penDown() {
+ penDown = true;
+ }
+
+ @Override
+ public synchronized void setSpeed(int speed) {
+ this.speed = Math.min(Math.max(MIN_SPEED, speed), MAX_SPEED);
+ }
+
+ @Override
+ public void addKeyboardAdapter(final KeyboardAdapter adapter) {
+ SwingUtilities.invokeLater(() -> {
+ RobotWindow window = RobotWindow.getInstance();
+ KeyListener[] listeners = window.getKeyListeners();
+ for (KeyListener listener : listeners) {
+ if (listener instanceof KeyboardAdapter) {
+ KeyboardAdapter a = (KeyboardAdapter) listener;
+ if (a.robot == adapter.robot) {
+ window.removeKeyListener(a);
+ break;
+ }
+ }
+ }
+ adapter.setRobot(Robot.this);
+ window.addKeyListener(adapter);
+ });
+ }
+
+ private enum TimeQuantum {
+ TICK
+ }
+
+ ActionListener getTickerListener() {
+ return e -> {
+ leakyBucket.offer(TimeQuantum.TICK);
+ window.repaint();
+ };
+ }
+
+ public static class Pos {
+ private final float x;
+ private final float y;
+
+ public Pos(float x, float y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public float getX() {
+ return x;
+ }
-import javax.swing.JOptionPane;
-
-public class Robot{
-
- private static final int WIDTH = 1780;
- private static final int HEIGHT = 1024;
-
- private boolean isVisible;
- private boolean penDown;
- private boolean isSparkling;
-
- private float xPos;
- private float yPos;
- private int angle;
- private int newAngle;
- private int speed;
- private int moveDistance;
- private int distanceMoved;
-
- private int sx;
- private int sy;
- private int tx;
- private int ty;
- private int penSize;
-
- private Color penColor;
-
- private long startTime;
-
- private RobotImage rImage;
-
- private Line currentLine;
- private ArrayList lines;
-
- private static int count = 0;
- private static Color windowColor;
- private static RobotWindow window;
-
- public Robot(){
- this(WIDTH / 2, HEIGHT / 2);
- }
-
- public Robot(String fileName)
- {
- this(WIDTH / 2, HEIGHT / 2, fileName);
- }
-
- public Robot(int x, int y)
- {
- this(x, y, "rob");
- }
-
- public Robot(int x, int y, String fileName)
- {
- xPos = x;
- yPos = y;
- angle = 0;
- speed = 1;
- newAngle = 0;
- moveDistance = 0;
- distanceMoved = 0;
- startTime = 0;
-
- sx = 0;
- sy = 0;
- tx = 0;
- ty = 0;
- penSize = 1;
- penColor = Color.BLACK;
-
- isVisible = true;
- penDown = false;
- isSparkling = false;
-
- rImage = new RobotImage((int)xPos, (int)yPos);
-
- currentLine = new Line(0, 0, 0, 0, 0, penColor);
- lines = new ArrayList();
-
- if(count == 0)
- {
- windowColor = new Color(220, 220, 220);
- window = new RobotWindow(WIDTH, HEIGHT, windowColor);
- }
-
- count++;
- loadDefaultRobot(fileName);
- window.addRobot(this);
- }
-
- public void draw(Graphics2D g)
- {
- for(int i = 0; i < lines.size(); i++)
- {
- Line l = lines.get(i);
- l.draw(g);
- }
-
- if(penDown)//draws under robot
- {
- currentLine.draw(g);
- }
-
- if(isVisible)
- {
- rImage.draw(g);
- }
-
- if(penDown)//draws over robot
- {
- g.setColor(penColor);
- int pSize = penSize + 4;
- int newX = (int) (xPos - (pSize / 2));
- int newY = (int) (yPos - (pSize / 2));
- g.fillOval(newX, newY, pSize, pSize);
- }
-
- if(isSparkling)
- {
- Random r = new Random();
- int xDot = r.nextInt(100) - 50;
- int yDot = r.nextInt(100) - 50;
- g.setColor(Color.WHITE);
- g.fillRect((int)(xPos + xDot), (int)(yPos + yDot), 5, 5);
- }
- }
-
- public void update()
- {
- float cos = (float)Math.cos(Math.toRadians(-angle));
- float sin = (float)Math.sin(Math.toRadians(-angle));
-
- if(distanceMoved < moveDistance)
- {
- int difference = moveDistance - distanceMoved;
-
- if(difference < speed)
- {
- float nextX = difference * sin;
- float nextY = difference * cos;
- xPos -= nextX;
- yPos -= nextY;
- distanceMoved += difference;
- }
- else
- {
- float nextX = speed * sin;
- float nextY = speed * cos;
- xPos -= nextX;
- yPos -= nextY;
- distanceMoved += speed;
- }
- }
- else if(distanceMoved > moveDistance)
- {
- int difference = distanceMoved - moveDistance;
-
- if(difference < speed)
- {
- float nextX = difference * sin;
- float nextY = difference * cos;
- xPos += nextX;
- yPos += nextY;
- distanceMoved -= (distanceMoved - moveDistance);
- }
- else
- {
- float nextX = speed * sin;
- float nextY = speed * cos;
- xPos += nextX;
- yPos += nextY;
- distanceMoved -= speed;
- }
- }
-
- tx = (int)xPos;
- ty = (int)yPos;
-
- if(penDown)
- {
- currentLine = new Line(sx, sy, tx, ty, penSize, penColor);
-
- if(moveDistance == distanceMoved)
- {
- lines.add(currentLine);
- }
- }
-
- if(angle < newAngle)
- {
- rImage.rotate(-1);
- angle++;
- }
- else if(angle > newAngle)
- {
- rImage.rotate(1);
- angle--;
- }
-
- rImage.x = (int)xPos;
- rImage.y = (int)yPos;
- }
-
- public void changeRobot(String fileName)
- {
- fileName += ".robi";
- try
- {
- FileInputStream fis = new FileInputStream(fileName);
- int fileSize = Util.getFileSize(fis);
- fis.close();
-
- fis = new FileInputStream(fileName);
- byte[] buffer = Util.readToBuffer(fis, fileSize);
- fis.close();
-
- loadPixels(buffer);
- }
- catch (Exception e)
- {
- JOptionPane.showMessageDialog(null, "There was an error loading your file.");
- System.out.println("changeRobot");
- loadDefaultRobot();
- }
- }
-
- public void setPenColor(Color c)
- {
- penColor = c;
- }
-
- public void setPenColor(int r, int g, int b)
- {
- r = Util.clamp(r, 0, 255);
- g = Util.clamp(r, 0, 255);
- b = Util.clamp(b, 0, 255);
-
- penColor = new Color(r, g, b);
- }
-
- public static void setWindowColor(Color c)
- {
- if(count != 0)
- {
- window.setWinColor(c);
- }
- }
-
- public static void setWindowColor(int r, int g, int b)
- {
- if(count != 0)
- {
- r = Util.clamp(r, 0, 255);
- g = Util.clamp(r, 0, 255);
- b = Util.clamp(b, 0, 255);
-
- window.setWinColor(new Color(r, g, b));
- }
- }
-
- public void setPenWidth(int size)
- {
- penSize = size;
- }
-
- public void clear()
- {
- lines.clear();
- window.update(this);
- }
-
- public void sparkle()
- {
- isSparkling = true;
- }
-
- public void unSparkle()
- {
- isSparkling = false;
- }
-
- public void show()
- {
- isVisible = true;
- update();
- }
-
- public void hide()
- {
- isVisible = false;
- update();
- }
-
- public void move(int distance)
- {
- distanceMoved = 0;
- moveDistance = distance;
-
- sx = (int)xPos;
- sy = (int)yPos;
- tx = (int)xPos;
- ty = (int)yPos;
-
- if(penDown)
- {
- currentLine = new Line(sx, sy, tx, ty, penSize, penColor);
- }
-
- startTime = System.currentTimeMillis();
-
- while(distanceMoved != moveDistance)
- {
- if((System.currentTimeMillis() - startTime) > (1000 / 60))
- {
- window.update(this);
- startTime = System.currentTimeMillis();
- }
- }
- }
-
- public void moveTo(int x, int y)
- {
- xPos = x;
- yPos = y;
- window.update(this);
- }
-
- public void turn(int degrees)
- {
- newAngle = angle + degrees;
-
- startTime = System.currentTimeMillis();
-
- while(angle != newAngle)
- {
- if((System.currentTimeMillis() - startTime) > (10 - speed))
- {
- window.update(this);
- startTime = System.currentTimeMillis();
- }
- }
- }
-
- public void penUp()
- {
- penDown = false;
- }
-
- public void penDown()
- {
- penDown = true;
- }
-
- public void loadDefaultRobot()
- {
- loadDefaultRobot("rob");
- }
-
- private void loadDefaultRobot(String s)
- {
- s += ".robi";
-
- try
- {
- InputStream is = this.getClass().getResourceAsStream(s);
- int fileSize = Util.getFileSize(is);
- is.close();
-
- is = this.getClass().getResourceAsStream(s);
- byte[] buffer = Util.readToBuffer(is, fileSize);
- is.close();
-
- loadPixels(buffer);
- }
- catch(Exception e)
- {
- JOptionPane.showMessageDialog(null, "There was an error loading your file.");
- System.out.println("loadDefaultRobot");
- loadDefaultRobot();
- }
-
- window.update(this);
- }
-
- public void setSpeed(int s)
- {
- s = Util.clamp(s, 0, 10);
-
- speed = s;
- }
-
- public void setAngle(int a)
- {
- int turnAmt = angle - a;
- rImage.rotate(turnAmt);
- angle = a;
- }
-
- public void setRandomPenColor() {
- Random random = new Random();
- this.penColor = new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
- }
-
- private void loadPixels(byte[] buf)
- {
- try
- {
- int ctr = 0;
-
- for(int i = 0; i < buf.length;)
- {
- byte[] num = new byte[4];
-
- num[0] = buf[i++];
- num[1] = buf[i++];
- num[2] = buf[i++];
- num[3] = buf[i++];
-
- int x = ByteBuffer.wrap(num).getInt();
-
- num[0] = buf[i++];
- num[1] = buf[i++];
- num[2] = buf[i++];
- num[3] = buf[i++];
-
- int y = ByteBuffer.wrap(num).getInt();
-
- num[0] = buf[i++];
- num[1] = buf[i++];
- num[2] = buf[i++];
- num[3] = buf[i++];
-
- int r = ByteBuffer.wrap(num).getInt();
-
- num[0] = buf[i++];
- num[1] = buf[i++];
- num[2] = buf[i++];
- num[3] = buf[i++];
-
- int g = ByteBuffer.wrap(num).getInt();
-
- num[0] = buf[i++];
- num[1] = buf[i++];
- num[2] = buf[i++];
- num[3] = buf[i++];
-
- int b = ByteBuffer.wrap(num).getInt();
-
- Color c;
-
- if(r == 220 &&
- g == 220 &&
- b == 220)
- {
- c = new Color (0, 0, 0, 0);
- }
- else
- {
- c = new Color(r, g, b);
- }
-
- rImage.setPixel(ctr++, x, y, c);
- }
- }
- catch(Exception e)
- {
- JOptionPane.showMessageDialog(null, "There was an error loading your file.");
- System.out.println("loadPixels");
- }
- }
-}
\ No newline at end of file
+ public float getY() {
+ return y;
+ }
+ }
+}
diff --git a/src/org/jointheleague/graphical/robot/RobotImage.java b/src/org/jointheleague/graphical/robot/RobotImage.java
index df9f040..87f2226 100644
--- a/src/org/jointheleague/graphical/robot/RobotImage.java
+++ b/src/org/jointheleague/graphical/robot/RobotImage.java
@@ -1,63 +1,92 @@
package org.jointheleague.graphical.robot;
-import java.awt.Color;
-import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+import javax.imageio.ImageIO;
+import javax.swing.JOptionPane;
+
+/**
+ * Utility class for loading images in robi format.
+ *
+ * @author David Dunn & Erik Colban © 2016
+ *
+ */
public class RobotImage {
- Pixel[] pix;
-
- public int x;
- public int y;
- public int width;
- public int height;
-
- public RobotImage(int ix, int iy)
- {
- width = 100;
- height = 100;
- x = ix;
- y = iy;
- pix = new Pixel[width * height];
-
- int ctr = 0;
- for(int i = 0; i < width; i++)
- {
- for(int j = 0; j < height; j++)
- {
- pix[ctr++] = new Pixel(i , j);
+ private static final int IMG_WIDTH = 100;
+ private static final int IMG_HEIGHT = 100;
+ private static final int PIXEL_LENGTH = 20; // in bytes
+
+ public static BufferedImage loadDefaultRobi() {
+ return loadRobi("rob");
+ }
+
+ public static BufferedImage loadRobi(String s) {
+ s = String.format("res/%s.robi", s);
+ BufferedImage img = new BufferedImage(IMG_WIDTH, IMG_HEIGHT,
+ BufferedImage.TYPE_INT_ARGB);
+
+ try (InputStream is = RobotImage.class.getResourceAsStream(s)) {
+ if (is == null) {
+ throw new IOException("File not found: " + s);
}
+ byte[] buf = new byte[PIXEL_LENGTH * 256];
+ IntBuffer ibuf = ByteBuffer.wrap(buf).asIntBuffer();
+ int offset = 0;
+ int len;
+ while ((len = is.read(buf, offset, buf.length - offset)) != -1) {
+ len += offset;
+ offset = len % PIXEL_LENGTH;
+ len -= offset;
+ for (int i = 0; i < len; i += PIXEL_LENGTH) {
+ readPixel(img, ibuf, i / 4);
+ }
+ for (int i = 0; i < offset; i++) {
+ buf[i] = buf[len + i];
+ }
+ }
+ } catch (IOException e) {
+ JOptionPane.showMessageDialog(null,
+ "There was an error loading your file.");
+ System.out.println("RobotImage: loadRobi\n" + e.getMessage());
+ img = loadDefaultRobi();
}
+ return img;
}
-
- public void draw(Graphics2D g)
- {
- for(int i = 0; i < pix.length; i++)
- {
- int dx = ((int)pix[i].x + x) - (width / 2);
- int dy = ((int)pix[i].y + y) - (height / 2);
-
- g.setColor(pix[i].getColor());
- g.drawRect(dx, dy, 1, 1);
+
+ private static void readPixel(BufferedImage img, IntBuffer ibuf, int pos) {
+ int x = ibuf.get(pos++);
+ int y = ibuf.get(pos++);
+
+ // Next 3 ints are the r, g, b components of the color
+ int rgb = 0;
+ for (int i = 0; i < 3; i++) {
+ rgb = rgb << 8 | ibuf.get(pos++) & 0xff;
}
- }
-
- public void rotate(int angle)
- {
- for(int i = 0; i < pix.length; i++)
- {
- pix[i].rotateAroundPoint(angle, width / 2, height / 2);
+ // The color 0xdcdcdc is chosen to encode transparency
+ if (rgb != 0xdcdcdc) {
+ rgb |= 0xff000000;
}
+
+ img.setRGB(x, y, rgb);
}
-
- public void rotateAroundPoint(int angle, int px, int py)
- {
- for(int i = 0; i < pix.length; i++)
+
+ public static BufferedImage loadImage(File file) {
+ try {
+ BufferedImage image = ImageIO.read(file);
+ if (image != null) {
+ return image;
+ }
+ } catch (IOException e)
{
- pix[i].rotateAroundPoint(angle, px, py);
+ System.out.println(e.getMessage());
+ return loadDefaultRobi();
}
+ return loadDefaultRobi();
}
-
- public void setPixel(int index, int x, int y, Color c)
- {
- pix[index] = new Pixel(x, y, c);
- }
+
}
diff --git a/src/org/jointheleague/graphical/robot/RobotInterface.java b/src/org/jointheleague/graphical/robot/RobotInterface.java
new file mode 100644
index 0000000..7123b9f
--- /dev/null
+++ b/src/org/jointheleague/graphical/robot/RobotInterface.java
@@ -0,0 +1,291 @@
+package org.jointheleague.graphical.robot;
+
+import java.awt.*;
+import java.awt.geom.PathIterator;
+import java.awt.image.BufferedImage;
+
+public interface RobotInterface {
+
+ /**
+ * Changes the image of the Robot
+ *
+ * @param im a BufferedImage containing the robot image. It does not need
+ * to be to scale since it will be scaled to the appropriate
+ * size.
+ */
+ void changeRobot(BufferedImage im);
+
+ /**
+ * Changes the image of the Robot
+ *
+ * @param urlName The URL of the image that specifies the Robot's image.
+ */
+ void changeRobot(String urlName);
+
+ int getPenWidth();
+
+ /**
+ * Sets the pen size.
+ *
+ * @param size the new pen size given as an integer between 1 and 10.
+ */
+ void setPenWidth(int size);
+
+ Color getPenColor();
+
+ /**
+ * Sets the pen color
+ *
+ * @param color the new pen color
+ */
+ void setPenColor(Color color);
+
+ /**
+ * Sets the pen color given the red, green and blue components of the new
+ * color. The components are specified as an integer between 0 and 255.
+ *
+ * @param r the red component of the new color
+ * @param g the green component of the new color
+ * @param b the blue component of the new color
+ */
+ void setPenColor(int r, int g, int b);
+
+ /**
+ * Sets the pen color to a random color.
+ */
+ void setRandomPenColor();
+
+ /**
+ * Removes all lines drawn by this Robot.
+ */
+ void clearDrawables();
+
+ /**
+ * Makes the image of the Robot small
+ */
+ void miniaturize();
+
+ /**
+ * Makes the image of the Robot big
+ */
+ void expand();
+
+ /**
+ * Set the position of the robot to (x, y) while maintaining its direction.
+ *
+ * @param x the x-coordinate of the new position
+ * @param y the y-coordinate of the new position
+ */
+ void setPos(float x, float y);
+
+ /**
+ * Gets the robot's angle of orientation in degrees.
+ * An angle of 0 means that the robot is pointing straight up and the angle
+ * increases as the robot turns clockwise.
+ *
+ * @return the angle of the robot
+ */
+ double getAngle();
+
+ /**
+ * Set the robot's angle of orientation.
+ *
+ * @param a the angle in radians
+ * @see #getAngle()
+ */
+ void setAngle(double a);
+
+ /**
+ * Makes the Robot sparkle.
+ */
+ void sparkle();
+
+ /**
+ * Removes sparkles
+ */
+ void unSparkle();
+
+ /**
+ * Make the Robot invisible. The Robot is visible initially.
+ */
+ void hide();
+
+ /**
+ * Makes the Robot visible
+ */
+ void show();
+
+ /**
+ * Makes the robot move a given distance. A negative distance makes the
+ * robot move backwards.
+ *
+ * @param distance the distance to move in units of points
+ */
+ void move(int distance);
+
+ /**
+ * Makes the Robot move one step. If the sgn is negative, the Robot moves
+ * one step backwards. The step size depends on the Robot's speed. This
+ * method is intended to be used by a KeyboardAdapter.
+ *
+ * @param sgn if positive the Robot moves forward, if negative the Robot
+ * moves backwards.
+ * @throws InterruptedException if interrupted before making the turn (which is very unlikely
+ * to happen).
+ * @throws IllegalArgumentException if sgn is 0.
+ */
+ void microMove(int sgn) throws InterruptedException;
+
+ /**
+ * Makes the Robot turn in place a given number of degrees. If the argument
+ * is positive, the Robot turn clockwise, if negative the Robot turns
+ * counter-clockwise.
+ *
+ * @param degrees The number of degrees to turn.
+ */
+ void turn(double degrees);
+
+ /**
+ * Turn the robot in place until it has reached an orientation given in degrees.
+ * Zero is up, 90 is right.
+ *
+ * @param degrees the desired orientation.
+ */
+ void turnTo(double degrees);
+
+ /**
+ * Makes the Robot turn in place a small angle. If the argument is positive,
+ * the Robot turn clockwise, if negative the Robot turns counter-clockwise.
+ * The angle turn is dependent on the Robot's speed.
+ *
+ * @param sgn The sign of the direction to turn.
+ * @throws InterruptedException if interrupted before making the turn (which is very unlikely
+ * to happen).
+ * @throws IllegalArgumentException if the sgn is 0.
+ */
+ void microTurn(int sgn) throws InterruptedException;
+
+ /**
+ * Waits a given number of milliseconds.
+ *
+ * @param millis the number of milliseconds to wait
+ */
+ void sleep(int millis);
+
+ /**
+ * Places the robot at (x, y)
+ *
+ * @param x the x-coordinate
+ * @param y the y-coordinate
+ * @deprecated Use {@link #setPos(float x, float y)}
+ */
+ @Deprecated
+ void moveTo(float x, float y);
+
+ /**
+ * Move the Robot to a given position. The Robot does not draw any line
+ * regardless of whether pen is up or down. Unless jump is true,
+ * if necessary, turn the robot first such that it is heading in the right
+ * direction before moving the robot.
+ *
+ * @param x the x-coordinate of the new position
+ * @param y the y-coordinate of the new position
+ * @param relative if true, x and y a relative to the robot's current position
+ */
+ void moveTo(float x, float y, boolean relative);
+
+ /**
+ * Move the robot forward to a given position. If necessary, turn the robot
+ * first such that it is heading in the right direction.
+ *
+ * @param x the x-coordinate of the robot's destination
+ * @param y the y-coordinate of the robot's destination
+ * @param relative if true, x and y are given relative to the robot's current
+ * position
+ */
+ void lineTo(float x, float y, boolean relative);
+
+ /**
+ * Move the robot along a quadratic curve given by the robot's current position
+ * and the control points (x1, y1) and (x2, y2). If necessary, turn the robot
+ * first such that it is heading in the right direction.
+ *
+ * @param x1 the x-coordinate of the first control point
+ * @param y1 the y-coordinate of the first control point
+ * @param x2 the x-coordinate of the second control point
+ * @param y2 the y-coordinate of the second control point
+ * @param relative if true, the coordinates are give relative to the robot's
+ * current position
+ */
+ void quadTo(float x1, float y1, float x2, float y2, boolean relative);
+
+ /**
+ * Move the robot along a cubic curve given by the robot's current position
+ * and the control points (x1, y1), (x2, y2) and (x3, y3). If necessary, turn
+ * the robot first such that it is heading in the right direction.
+ *
+ * @param x1 the x-coordinate of the first control point
+ * @param y1 the y-coordinate of the first control point
+ * @param x2 the x-coordinate of the second control point
+ * @param y2 the y-coordinate of the second control point
+ * @param x3 the x-coordinate of the third control point
+ * @param y3 the y-coordinate of the third control point
+ * @param relative if true, the coordinates are give relative to the robot's
+ * current position
+ */
+ void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3, boolean relative);
+
+ /**
+ * Move the robot along a path.
+ *
+ * @param pathIterator a PathIterator specifying the path
+ * @param fill if true and the robot's pen is down, fill the path
+ * with the current pen color, otherwise draw the path
+ */
+ void followPath(PathIterator pathIterator, boolean fill);
+
+ /**
+ * Move the robot along a path and, if the pen is down, draw the path
+ *
+ * @param pathIterator a PathIterator specifying the path
+ */
+ void followPath(PathIterator pathIterator);
+
+ /**
+ * @return the x-coordinate of the robot's position
+ */
+ float getX();
+
+ /**
+ * @return the y-coordinate of the robot's position
+ */
+ float getY();
+
+ /**
+ * Lifts the pen, i.e., the Robot stops drawing lines or curves.
+ */
+ void penUp();
+
+ /**
+ * Set the pen down, i.e., the Robot traces its movements with lines or curves.
+ */
+ void penDown();
+
+ /**
+ * Sets the speed of the Robot.
+ *
+ * @param speed the speed specified as a number between 1 and 100.
+ */
+ void setSpeed(int speed);
+
+ /**
+ * Adds a {@link KeyboardAdapter} to the robot. It is possible to add more
+ * than one KeyboardAdapter, each controlling a different Robot. If two
+ * KeyboardAdapters controlling the same Robot are added, the last one added
+ * replaces the first.
+ *
+ * @param adapter the KeyboardAdapter
+ * @see KeyboardAdapter
+ */
+ void addKeyboardAdapter(KeyboardAdapter adapter);
+}
diff --git a/src/org/jointheleague/graphical/robot/RobotWindow.java b/src/org/jointheleague/graphical/robot/RobotWindow.java
index 7450b08..5386ea0 100644
--- a/src/org/jointheleague/graphical/robot/RobotWindow.java
+++ b/src/org/jointheleague/graphical/robot/RobotWindow.java
@@ -1,69 +1,154 @@
package org.jointheleague.graphical.robot;
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
+
+import javax.imageio.ImageIO;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionListener;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
-import javax.swing.JFrame;
-import javax.swing.JPanel;
-
-public class RobotWindow extends JPanel{
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- private int width;
- private int height;
- private JFrame window;
- private Color winColor;
-
- ArrayList robotList;
-
- public RobotWindow(int w, int h, Color c)
- {
- width = w;
- height = h;
- window = new JFrame();
- window.add(this);
- window.setSize(w, h);
- window.setVisible(true);
- window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- window.setResizable(false);
-
- winColor = c;
-
- robotList = new ArrayList();
- }
-
- public void setWinColor(Color c)
- {
- winColor = c;
- repaint();
- }
-
- public void paint(Graphics g)
- {
- Graphics2D g2 = (Graphics2D)g;
-
- g2.setColor(winColor);
- g2.fillRect(0, 0, width, height);
-
- for(int i = 0; i < robotList.size(); i++)
- {
- Robot r = robotList.get(i);
- r.draw(g2);
- }
- }
-
- public void addRobot(Robot r)
- {
- robotList.add(r);
- update(r);
- }
-
- public void update(Robot r)
- {
- r.update();
- repaint();
- }
+/**
+ * Singleton class that defines the window in which the Robots move around.
+ *
+ * @author David Dunn & Erik Colban © 2016
+ */
+@SuppressWarnings("serial")
+public class RobotWindow extends JPanel {
+
+ private static final int WINDOW_HEIGHT = 600;
+ private static final int WINDOW_WIDTH = 900;
+ private static final Color DEFAULT_WINDOW_COLOR = new Color(0xdcdcdc);
+ private static final int MARGIN = 10;
+ private static final RobotWindow INSTANCE = new RobotWindow(DEFAULT_WINDOW_COLOR);
+
+ private Color winColor;
+
+ private ArrayList robotList;
+ private Timer ticker;
+
+ private BufferedImage leagueLogo;
+ private boolean usingCustomImage;
+
+ private boolean guiHasBeenBuilt = false;
+
+ private JFrame frame;
+
+ private RobotWindow(Color color) {
+ winColor = color;
+ robotList = new ArrayList<>();
+ try {
+ leagueLogo = ImageIO.read(this.getClass().getResourceAsStream("res/league_logo.png"));
+ } catch (IOException e) {
+ System.err.println("Cannot load background image.");
+ }
+ usingCustomImage = false;
+ }
+
+ /**
+ * Returns the single instance of the RobotWindow
+ *
+ * @return the single instance
+ */
+ public static RobotWindow getInstance() {
+ return INSTANCE;
+ }
+
+ private void buildGui() {
+ frame = new JFrame();
+ setPreferredSize(new Dimension(WINDOW_WIDTH, WINDOW_HEIGHT));
+ frame.add(this);
+ // frame.setSize(Toolkit.getDefaultToolkit().getScreenSize());
+ frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+ frame.setResizable(true);
+ frame.pack();
+ frame.setVisible(true);
+ setFocusable(true);
+ }
+
+ public void paintComponent(Graphics g) {
+ Graphics2D g2 = (Graphics2D) g;
+
+ g2.setColor(winColor);
+ g2.fillRect(0, 0, getWidth(), getHeight());
+ if (usingCustomImage) {
+ g2.drawImage(leagueLogo, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, null);
+ } else {
+ int imgX = getWidth() - leagueLogo.getWidth() - MARGIN;
+ int imgY = MARGIN;
+ g2.drawImage(leagueLogo, imgX, imgY, null);
+ }
+
+ RenderingHints renderingHints = new RenderingHints(
+ RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ g2.setRenderingHints(renderingHints);
+ for (Robot robot : robotList) {
+ robot.draw(g2);
+ }
+ }
+
+ /**
+ * Adds a robot to the window
+ *
+ * @param robot the robot
+ */
+ void addRobot(final Robot robot) {
+ final ActionListener tickerListener = robot.getTickerListener();
+ try {
+ SwingUtilities.invokeAndWait(() -> {
+ if (!guiHasBeenBuilt) {
+ buildGui();
+ ticker = new Timer(Robot.TICK_LENGTH, tickerListener);
+ ticker.start();
+ guiHasBeenBuilt = true;
+ } else {
+ ticker.addActionListener(tickerListener);
+ }
+ robotList.add(robot);
+ repaint();
+ });
+ } catch (InvocationTargetException | InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Set the RobotWindow's background Color. This method should be invoked on the EDT only.
+ *
+ * @param color the background color
+ */
+ public void setWinColor(Color color) {
+ winColor = color;
+ repaint();
+ }
+
+ /**
+ * Set the RobotWindow's background Image. This method should be invoked on the EDT only.
+ *
+ * @param imageLocation the location of the background image
+ */
+ public void setBackgroundImage(String imageLocation) {
+ try {
+ leagueLogo = ImageIO.read(this.getClass().getResourceAsStream("../../../../" + imageLocation));
+ } catch (IOException e) {
+ System.err.println("Cannot load background image.");
+ }
+ usingCustomImage = true;
+ repaint();
+ }
+
+
+ /**
+ * Sets the dimension of the panel containing the robots. This method should be invoked on the EDT only.
+ *
+ * @param width the width of the panel
+ * @param height the height of the panel
+ */
+ public void setWindowSize(int width, int height) {
+ setPreferredSize(new Dimension(width, height));
+ frame.pack();
+ }
+
}
diff --git a/src/org/jointheleague/graphical/robot/Util.java b/src/org/jointheleague/graphical/robot/Util.java
deleted file mode 100644
index 0f336a1..0000000
--- a/src/org/jointheleague/graphical/robot/Util.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package org.jointheleague.graphical.robot;
-
-import java.io.FileInputStream;
-import java.io.InputStream;
-
-import javax.swing.JOptionPane;
-
-public class Util {
-
- public static int clamp(int val, int lo, int hi)
- {
- if(val < lo)
- {
- return lo;
- }
- else if(val > hi)
- {
- return hi;
- }
- else
- {
- return val;
- }
- }
-
- public static byte[] readToBuffer(FileInputStream fis, int fileSize)
- {
- byte[] buf = new byte[fileSize];
-
- try
- {
- for(int i = 0; i < fileSize; i++)
- {
- buf[i] = (byte)fis.read();
- }
- }
- catch (Exception e)
- {
- JOptionPane.showMessageDialog(null, "There was an error loading your file.");
- System.out.println("readToBuffer");
- }
-
- return buf;
- }
-
- public static byte[] readToBuffer(InputStream fis, int fileSize)
- {
- byte[] buf = new byte[fileSize];
-
- try
- {
- for(int i = 0; i < fileSize; i++)
- {
- buf[i] = (byte)fis.read();
- }
- }
- catch (Exception e)
- {
- JOptionPane.showMessageDialog(null, "There was an error loading your file.");
- System.out.println("readToBuffer");
- }
-
- return buf;
- }
-
- public static int getFileSize(FileInputStream f)
- {
- int ctr = 0;
- try
- {
- while(f.read() != -1)
- {
- ctr++;
- }
- }
- catch (Exception e)
- {
- JOptionPane.showMessageDialog(null, "There was an error loading your file.");
- System.out.println("getFileSize");
- }
-
- return ctr;
- }
-
- public static int getFileSize(InputStream f)
- {
- int ctr = 0;
- try
- {
- while(f.read() != -1)
- {
- ctr++;
- }
- }
- catch (Exception e)
- {
- JOptionPane.showMessageDialog(null, "There was an error loading your file.");
- System.out.println("getFileSize");
- }
-
- return ctr;
- }
-}
diff --git a/src/org/jointheleague/graphical/robot/Vector2D.java b/src/org/jointheleague/graphical/robot/Vector2D.java
deleted file mode 100644
index c02bb6e..0000000
--- a/src/org/jointheleague/graphical/robot/Vector2D.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.jointheleague.graphical.robot;
-public class Vector2D {
- protected float x;
- protected float y;
-
- public Vector2D()
- {
- this(0, 0);
- }
-
- public Vector2D(float x, float y)
- {
- this.x = x;
- this.y = y;
- }
-
- public void rotate(int angle)
- {
- float cos = (float)Math.cos(Math.toRadians(angle));
- float sin = (float)Math.sin(Math.toRadians(angle));
- float nx = (x * cos) - (y * sin);
- float ny = (x * sin) + (y * cos);
-
- x = nx;
- y = ny;
- }
-
- public void rotateAroundPoint(int angle, float px, float py)
- {
- float cos = (float)Math.cos(Math.toRadians(angle));
- float sin = (float)Math.sin(Math.toRadians(angle));
- float originX = px - x;
- float originY = y - py;
- float nx = (originX * cos) - (originY * sin);
- float ny = (originX * sin) + (originY * cos);
-
- x = px - nx;
- y = py + ny;
- }
-}
\ No newline at end of file
diff --git a/src/org/jointheleague/graphical/robot/curves/Close.java b/src/org/jointheleague/graphical/robot/curves/Close.java
new file mode 100644
index 0000000..561cc55
--- /dev/null
+++ b/src/org/jointheleague/graphical/robot/curves/Close.java
@@ -0,0 +1,86 @@
+package org.jointheleague.graphical.robot.curves;
+
+import org.jointheleague.graphical.robot.Robot;
+
+import java.awt.*;
+import java.awt.geom.Path2D;
+
+final public class Close implements Segment {
+
+ private final float startX;
+ private final float startY;
+ private final float[] ctrlPoints;
+
+ /**
+ * Constructor
+ *
+ * @param x x-coordinate of the segment's starting point
+ * @param y y-coordinate of the segment's starting point
+ * @param ctrlPoints an array of length at least 2 that
+ * contains the x- and y-coordinates of the segment's end point.
+ * @param lineSize the line width used to draw the segment
+ * @param color the color used to draw the segment
+ */
+ public Close(float x, float y, float[] ctrlPoints, int lineSize, Color color) {
+ this.startX = x;
+ this.startY = y;
+ this.ctrlPoints = ctrlPoints;
+ }
+
+ @Override
+ public Segment subSegment(float t) {
+ if (1F <= t) return this;
+ Robot.Pos pos = getPos(t);
+ return new Line(startX, startY, new float[]{pos.getX(), pos.getY()}, 0, null);
+ }
+
+ @Override
+ public Robot.Pos getPos(float t) {
+ if (t <= 0.0F) return new Robot.Pos(startX, startY);
+ if (1.0F <= t) return new Robot.Pos(ctrlPoints[0], ctrlPoints[1]);
+ float u = 1F - t;
+ return new Robot.Pos(
+ u * startX + t * ctrlPoints[0],
+ u * startY + t * ctrlPoints[1]);
+ }
+
+ @Override
+ public double getStartAngle() {
+ if (ctrlPoints[0] == startX && ctrlPoints[1] == startY) return Double.NaN;
+ return Math.atan2(ctrlPoints[0] - startX, -ctrlPoints[1] + startY);
+ }
+
+ @Override
+ public double getEndAngle() {
+ return getStartAngle();
+ }
+
+ @Override
+ public double getAngle(float t) {
+ return getStartAngle();
+ }
+
+ @Override
+ public float getSize() {
+ double a = ctrlPoints[0] - startX;
+ double b = ctrlPoints[1] - startY;
+ return (float) Math.sqrt(a * a + b * b);
+ }
+
+ @Override
+ public Path2D addTo(Path2D path2D) {
+ path2D.closePath();
+ return path2D;
+ }
+
+ @Override
+ public Path2D addTo(Path2D path2D, float t) {
+ if (1F < t) {
+ path2D.closePath();
+ } else {
+ final Robot.Pos pos1 = getPos(t);
+ path2D.lineTo(pos1.getX(), pos1.getY());
+ }
+ return path2D;
+ }
+}
diff --git a/src/org/jointheleague/graphical/robot/curves/Cubic.java b/src/org/jointheleague/graphical/robot/curves/Cubic.java
new file mode 100644
index 0000000..0b1bda0
--- /dev/null
+++ b/src/org/jointheleague/graphical/robot/curves/Cubic.java
@@ -0,0 +1,126 @@
+package org.jointheleague.graphical.robot.curves;
+
+import org.jointheleague.graphical.robot.Robot;
+
+import java.awt.*;
+import java.awt.geom.CubicCurve2D;
+import java.awt.geom.Path2D;
+
+final public class Cubic implements Drawable, Segment {
+
+ private final float startX;
+ private final float startY;
+ private final float[] ctrlPoints;
+ private final int lineSize;
+ private final Color color;
+ private final Line line;
+ private final Quad quad;
+
+ /**
+ * Constructor
+ *
+ * @param x x-coordinate of the segment's starting point
+ * @param y y-coordinate of the segment's starting point
+ * @param ctrlPoints an array of length at least 6 that
+ * contains the x- and y-coordinates of the segment's control points.
+ * @param lineSize the line width used to draw the segment
+ * @param color the color used to draw the segment
+ */
+ public Cubic(float x, float y, float[] ctrlPoints, int lineSize, Color color) {
+ this.startX = x;
+ this.startY = y;
+ this.ctrlPoints = ctrlPoints;
+ this.lineSize = lineSize;
+ this.color = color;
+ this.line = new Line(x, y, ctrlPoints, 0, null);
+ this.quad = new Quad(x, y, ctrlPoints, 0, null);
+ }
+
+ @Override
+ public void draw(Graphics2D g2) {
+ g2.setStroke(new BasicStroke(lineSize));
+ g2.setColor(color);
+ CubicCurve2D.Float cubic = new CubicCurve2D.Float(
+ startX, startY,
+ ctrlPoints[0], ctrlPoints[1],
+ ctrlPoints[2], ctrlPoints[3],
+ ctrlPoints[4], ctrlPoints[5]);
+ g2.draw(cubic);
+ }
+
+ @Override
+ public Segment subSegment(float t) {
+ Robot.Pos pos1 = line.getPos(t);
+ Robot.Pos pos2 = quad.getPos(t);
+ Robot.Pos pos3 = getPos(t);
+ float[] ctrlPoints = {
+ pos1.getX(), pos1.getY(),
+ pos2.getX(), pos2.getY(),
+ pos3.getX(), pos3.getY()};
+ return new Cubic(startX, startY, ctrlPoints, lineSize, color);
+ }
+
+ @Override
+ public Robot.Pos getPos(float t) {
+ if (t <= 0F) return new Robot.Pos(startX, startY);
+ if (1F <= t) return new Robot.Pos(ctrlPoints[4], ctrlPoints[5]);
+ final float u = 1 - t;
+ final float uu = u * u;
+ final float tt = t * t;
+ float c0 = uu * u;
+ float c1 = 3 * uu * t;
+ float c2 = 3 * u * tt;
+ float c3 = t * tt;
+ return new Robot.Pos(
+ c0 * startX + c1 * ctrlPoints[0] + c2 * ctrlPoints[2] + c3 * ctrlPoints[4],
+ c0 * startY + c1 * ctrlPoints[1] + c2 * ctrlPoints[3] + c3 * ctrlPoints[5]);
+ }
+
+ @Override
+ public double getStartAngle() {
+ if (ctrlPoints[0] == startX && ctrlPoints[1] == startY) return Double.NaN;
+ return Math.atan2(ctrlPoints[0] - startX, -ctrlPoints[1] + startY);
+ }
+
+ @Override
+ public double getEndAngle() {
+ if (ctrlPoints[4] == ctrlPoints[2] && ctrlPoints[5] == ctrlPoints[3]) return Double.NaN;
+ return Math.atan2(ctrlPoints[4] - ctrlPoints[2], -ctrlPoints[5] + ctrlPoints[3]);
+ }
+
+ @Override
+ public double getAngle(float time) {
+ if (time <= 0F) return getStartAngle();
+ if (1F <= time) return getEndAngle();
+ return subSegment(time).getEndAngle();
+ }
+
+ @Override
+ public float getSize() {
+ double a = ctrlPoints[0] - startX;
+ double b = ctrlPoints[1] - startY;
+ double c = ctrlPoints[2] - ctrlPoints[0];
+ double d = ctrlPoints[3] - ctrlPoints[1];
+ double e = ctrlPoints[4] - ctrlPoints[2];
+ double f = ctrlPoints[5] - ctrlPoints[3];
+ return (float) (Math.sqrt(a * a + b * b) + Math.sqrt(c * c + d * d) + Math.sqrt(e * e + f * f));
+ }
+
+ @Override
+ public Path2D addTo(Path2D path2D) {
+ path2D.curveTo(ctrlPoints[0], ctrlPoints[1], ctrlPoints[2], ctrlPoints[3], ctrlPoints[4], ctrlPoints[5]);
+ return path2D;
+ }
+
+ @Override
+ public Path2D addTo(Path2D path2D, float t) {
+ Robot.Pos pos1 = line.getPos(t);
+ Robot.Pos pos2 = quad.getPos(t);
+ Robot.Pos pos3 = getPos(t);
+ path2D.curveTo(
+ pos1.getX(), pos1.getY(),
+ pos2.getX(), pos2.getY(),
+ pos3.getX(), pos3.getY());
+ return path2D;
+ }
+}
diff --git a/src/org/jointheleague/graphical/robot/curves/Drawable.java b/src/org/jointheleague/graphical/robot/curves/Drawable.java
new file mode 100644
index 0000000..44db374
--- /dev/null
+++ b/src/org/jointheleague/graphical/robot/curves/Drawable.java
@@ -0,0 +1,12 @@
+package org.jointheleague.graphical.robot.curves;
+
+import java.awt.*;
+
+public interface Drawable {
+ /**
+ * Draws the drawable given a graphics context
+ *
+ * @param g2 a Graphics2D
+ */
+ void draw(Graphics2D g2);
+}
diff --git a/src/org/jointheleague/graphical/robot/curves/DynamicPath.java b/src/org/jointheleague/graphical/robot/curves/DynamicPath.java
new file mode 100644
index 0000000..adc2e86
--- /dev/null
+++ b/src/org/jointheleague/graphical/robot/curves/DynamicPath.java
@@ -0,0 +1,122 @@
+package org.jointheleague.graphical.robot.curves;
+
+import org.jointheleague.graphical.robot.Robot;
+
+import java.awt.*;
+import java.awt.geom.Path2D;
+import java.awt.geom.PathIterator;
+
+/**
+ * A Path that is followed by a Robot. Only the part of the path from
+ * the path's start to the robot's current position is drawn.
+ */
+final public class DynamicPath implements Drawable {
+
+ private Segment currentSegment;
+ private Path2D currentPath = new Path2D.Float();
+ private float time = 0F;
+ private final PathIterator pathIterator;
+ private Robot.Pos startingPoint;
+ private final int lineSize;
+ private final Color color;
+ private final Robot robot;
+ private final boolean fill;
+
+ /**
+ * Constructor
+ *
+ * @param pathIterator a PathIterator describing the path
+ * @param lineSize the line width used to draw the path.
+ * @param color the color used to draw the path
+ * @param robot a Robot that moves along the path
+ * @param fill if set to true, fill path else draw the outline
+ */
+ public DynamicPath(PathIterator pathIterator, int lineSize, Color color, Robot robot, boolean fill) {
+ this.pathIterator = pathIterator;
+ this.lineSize = lineSize;
+ this.color = color;
+ this.robot = robot;
+ this.fill = fill;
+ currentSegment = getCurrentSegment();
+ assert currentSegment != null;
+ double startAngle = currentSegment.getStartAngle();
+ if (!Double.isNaN(startAngle)) robot.turnTo(startAngle);
+ }
+
+ private Segment getCurrentSegment() {
+ assert !pathIterator.isDone();
+ float[] coordinates = new float[6];
+ float x = robot.getX();
+ float y = robot.getY();
+ int type = pathIterator.currentSegment(coordinates);
+ switch (type) {
+ case PathIterator.SEG_MOVETO:
+ startingPoint = new Robot.Pos(coordinates[0], coordinates[1]);
+ return new Move(x, y, coordinates);
+ case PathIterator.SEG_LINETO:
+ return new Line(x, y, coordinates, 0, null);
+ case PathIterator.SEG_QUADTO:
+ return new Quad(x, y, coordinates, 0, null);
+ case PathIterator.SEG_CUBICTO:
+ return new Cubic(x, y, coordinates, 0, null);
+ case PathIterator.SEG_CLOSE:
+ coordinates[0] = startingPoint.getX();
+ coordinates[1] = startingPoint.getY();
+ return new Close(x, y, coordinates, 0, null);
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Moves the robot forward on the path by an increment that
+ * is proportional to the speed.
+ *
+ * @param speed a double value that specifies the increment
+ */
+ public void incrementTime(double speed) {
+ time += speed / currentSegment.getSize();
+ Robot.Pos pos = currentSegment.getPos(time);
+ robot.setPos(pos.getX(), pos.getY());
+ double angle = currentSegment.getAngle(time);
+ if (!Double.isNaN(angle)) robot.setAngle(Math.toDegrees(angle));
+ if (time >= 1F) {
+ currentSegment.addTo(currentPath);
+ pathIterator.next();
+ if (!pathIterator.isDone()) {
+ currentSegment = getCurrentSegment();
+ assert currentSegment != null;
+ double startAngle = currentSegment.getStartAngle();
+ if (!Double.isNaN(startAngle)) robot.turnTo(startAngle);
+ time = 0F;
+ }
+ }
+ }
+
+ /**
+ * @return true if the robot has reached the end of the path.
+ */
+ public boolean isComplete() {
+ return pathIterator.isDone();
+ }
+
+ private Path2D getPath2D() {
+ if (0.0 < time && time < 1.0) {
+ Path2D path = new Path2D.Float(currentPath);
+ return currentSegment.addTo(path, time);
+ } else {
+ return currentPath;
+ }
+ }
+
+ @Override
+ public void draw(Graphics2D g2) {
+ g2.setStroke(new BasicStroke(lineSize));
+ g2.setColor(color);
+ if (fill) {
+ g2.fill(getPath2D());
+ } else {
+ g2.draw(getPath2D());
+ }
+ }
+}
diff --git a/src/org/jointheleague/graphical/robot/curves/Line.java b/src/org/jointheleague/graphical/robot/curves/Line.java
new file mode 100644
index 0000000..69b7e42
--- /dev/null
+++ b/src/org/jointheleague/graphical/robot/curves/Line.java
@@ -0,0 +1,97 @@
+package org.jointheleague.graphical.robot.curves;
+
+import org.jointheleague.graphical.robot.Robot;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
+
+final public class Line implements Drawable, Segment {
+
+ private final float startX;
+ private final float startY;
+ private final float[] ctrlPoints;
+ private final int lineSize;
+ private final Color color;
+
+ /**
+ * Constructor
+ *
+ * @param x x-coordinate of the segment's starting point
+ * @param y y-coordinate of the segment's starting point
+ * @param ctrlPoints an array of length at least 2 that
+ * contains the x- and y-coordinates of the segment's control points.
+ * @param lineSize the line width used to draw the segment
+ * @param color the color used to draw the segment
+ */
+ public Line(float x, float y, float[] ctrlPoints, int lineSize, Color color) {
+ this.startX = x;
+ this.startY = y;
+ this.ctrlPoints = ctrlPoints;
+ this.lineSize = lineSize;
+ this.color = color;
+ }
+
+ @Override
+ public void draw(Graphics2D g2) {
+ g2.setStroke(new BasicStroke(lineSize));
+ g2.setColor(color);
+ g2.draw(new Line2D.Float(startX, startY, ctrlPoints[0], ctrlPoints[1]));
+ }
+
+ @Override
+ public Segment subSegment(float t) {
+ if (1F <= t) return this;
+ Robot.Pos pos = getPos(t);
+ return new Line(startX, startY, new float[]{pos.getX(), pos.getY()},
+ lineSize, color);
+ }
+
+ @Override
+ public Robot.Pos getPos(float t) {
+ if (t <= 0.0F) return new Robot.Pos(startX, startY);
+ if (1.0F <= t) return new Robot.Pos(ctrlPoints[0], ctrlPoints[1]);
+ float u = 1F - t;
+ return new Robot.Pos(
+ u * startX + t * ctrlPoints[0],
+ u * startY + t * ctrlPoints[1]);
+ }
+
+ @Override
+ public double getStartAngle() {
+ if (ctrlPoints[0] == startX && ctrlPoints[1] == startY) return Double.NaN;
+ return Math.atan2(ctrlPoints[0] - startX, -ctrlPoints[1] + startY);
+ }
+
+ @Override
+ public double getEndAngle() {
+ return getStartAngle();
+ }
+
+ @Override
+ public double getAngle(float t) {
+ return getStartAngle();
+ }
+
+ @Override
+ public float getSize() {
+ double a = ctrlPoints[0] - startX;
+ double b = ctrlPoints[1] - startY;
+ return (float) Math.sqrt(a * a + b * b);
+ }
+
+ @Override
+ public Path2D addTo(Path2D path2D) {
+ path2D.lineTo(ctrlPoints[0], ctrlPoints[1]);
+ return path2D;
+ }
+
+ @Override
+ public Path2D addTo(Path2D path2D, float t) {
+ final Robot.Pos pos1 = getPos(t);
+ path2D.lineTo(pos1.getX(), pos1.getY());
+ return path2D;
+ }
+}
diff --git a/src/org/jointheleague/graphical/robot/curves/Move.java b/src/org/jointheleague/graphical/robot/curves/Move.java
new file mode 100644
index 0000000..b95a25d
--- /dev/null
+++ b/src/org/jointheleague/graphical/robot/curves/Move.java
@@ -0,0 +1,79 @@
+package org.jointheleague.graphical.robot.curves;
+
+import org.jointheleague.graphical.robot.Robot;
+
+import java.awt.geom.Path2D;
+
+final public class Move implements Segment {
+
+ private final float startX;
+ private final float startY;
+ private final float[] ctrlPoints;
+
+ /**
+ * Constructor. This segment is not drawn.
+ *
+ * @param x x-coordinate of the segment's starting point
+ * @param y y-coordinate of the segment's starting point
+ * @param ctrlPoints an array of length at least 2 that
+ * contains the x- and y-coordinates of the segment's control points.
+ *
+ */
+ public Move(float x, float y, float[] ctrlPoints) {
+ this.startX = x;
+ this.startY = y;
+ this.ctrlPoints = ctrlPoints;
+ }
+
+ @Override
+ public Segment subSegment(float t) {
+ Robot.Pos pos = getPos(t);
+ return new Move(startX, startY, new float[]{pos.getX(), pos.getY()});
+ }
+
+ @Override
+ public Robot.Pos getPos(float t) {
+ if (t <= 0.0F) return new Robot.Pos(startX, startY);
+ if (1.0F <= t) return new Robot.Pos(ctrlPoints[0], ctrlPoints[1]);
+ float u = 1F - t;
+ return new Robot.Pos(
+ u * startX + t * ctrlPoints[0],
+ u * startY + t * ctrlPoints[1]);
+ }
+
+ @Override
+ public double getStartAngle() {
+ if (ctrlPoints[0] == startX && ctrlPoints[1] == startY) return Double.NaN;
+ return Math.atan2(ctrlPoints[0] - startX, -ctrlPoints[1] + startY);
+ }
+
+ @Override
+ public double getEndAngle() {
+ return getStartAngle();
+ }
+
+ @Override
+ public double getAngle(float t) {
+ return getStartAngle();
+ }
+
+ @Override
+ public float getSize() {
+ double a = ctrlPoints[0] - startX;
+ double b = ctrlPoints[1] - startY;
+ return (float) Math.sqrt(a * a + b * b);
+ }
+
+ @Override
+ public Path2D addTo(Path2D path2D) {
+ path2D.moveTo(ctrlPoints[0], ctrlPoints[1]);
+ return path2D;
+ }
+
+ @Override
+ public Path2D addTo(Path2D path2D, float t) {
+ final Robot.Pos pos1 = getPos(t);
+ path2D.moveTo(pos1.getX(), pos1.getY());
+ return path2D;
+ }
+}
diff --git a/src/org/jointheleague/graphical/robot/curves/Quad.java b/src/org/jointheleague/graphical/robot/curves/Quad.java
new file mode 100644
index 0000000..23d563a
--- /dev/null
+++ b/src/org/jointheleague/graphical/robot/curves/Quad.java
@@ -0,0 +1,113 @@
+package org.jointheleague.graphical.robot.curves;
+
+import org.jointheleague.graphical.robot.Robot;
+
+import java.awt.*;
+import java.awt.geom.Path2D;
+import java.awt.geom.QuadCurve2D;
+
+final public class Quad implements Drawable, Segment {
+
+ private final float startX;
+ private final float startY;
+ private final float[] ctrlPoints;
+ private final int lineSize;
+ private final Color color;
+ private final Line line;
+
+ /**
+ * Constructor
+ *
+ * @param x x-coordinate of the segment's starting point
+ * @param y y-coordinate of the segment's starting point
+ * @param ctrlPoints an array of length at least 4 that
+ * contains the x- and y-coordinates of the segment's control points.
+ * @param lineSize the line width used to draw the segment
+ * @param color the color used to draw the segment
+ */
+ public Quad(float x, float y, float[] ctrlPoints, int lineSize, Color color) {
+ this.startX = x;
+ this.startY = y;
+ this.ctrlPoints = ctrlPoints;
+ this.lineSize = lineSize;
+ this.color = color;
+ this.line = new Line(x, y, ctrlPoints, 0, null);
+ }
+
+ @Override
+ public void draw(Graphics2D g2) {
+ g2.setStroke(new BasicStroke(lineSize));
+ g2.setColor(color);
+ QuadCurve2D quad = new QuadCurve2D.Float(
+ startX, startY, ctrlPoints[0], ctrlPoints[1], ctrlPoints[2], ctrlPoints[3]);
+ g2.draw(quad);
+ }
+
+ @Override
+ public Segment subSegment(float t) {
+ Robot.Pos pos1 = line.getPos(t);
+ Robot.Pos pos2 = getPos(t);
+
+ float[] ctrlPoints = {
+ pos1.getX(), pos1.getY(),
+ pos2.getX(), pos2.getY()};
+
+ return new Quad(startX, startY, ctrlPoints, lineSize, color);
+ }
+
+ @Override
+ public Robot.Pos getPos(float t) {
+ if (t <= 0F) return new Robot.Pos(startX, startY);
+ if (1F <= t) return new Robot.Pos(ctrlPoints[2], ctrlPoints[3]);
+ float u = 1F - t;
+ float c0 = u * u;
+ float c1 = 2 * u * t;
+ float c2 = t * t;
+ return new Robot.Pos(
+ c0 * startX + c1 * ctrlPoints[0] + c2 * ctrlPoints[2],
+ c0 * startY + c1 * ctrlPoints[1] + c2 * ctrlPoints[3]);
+
+ }
+
+ @Override
+ public double getStartAngle() {
+ if (ctrlPoints[0] == startX && ctrlPoints[1] == startY) return Double.NaN;
+ return Math.atan2(ctrlPoints[0] - startX, -ctrlPoints[1] + startY);
+ }
+
+ @Override
+ public double getEndAngle() {
+ if (ctrlPoints[2] == ctrlPoints[0] && ctrlPoints[3] == ctrlPoints[1]) return Double.NaN;
+ return Math.atan2(ctrlPoints[2] - ctrlPoints[0], -ctrlPoints[3] + ctrlPoints[1]);
+ }
+
+ @Override
+ public double getAngle(float time) {
+ if (time <= 0F) return getStartAngle();
+ if (1F <= time) return getEndAngle();
+ return subSegment(time).getEndAngle();
+ }
+
+ @Override
+ public float getSize() {
+ double a = ctrlPoints[0] - startX;
+ double b = ctrlPoints[1] - startY;
+ double c = ctrlPoints[2] - ctrlPoints[0];
+ double d = ctrlPoints[3] - ctrlPoints[1];
+ return (float) (Math.sqrt(a * a + b * b) + Math.sqrt(c * c + d * d));
+ }
+
+ @Override
+ public Path2D addTo(Path2D path2D) {
+ path2D.quadTo(ctrlPoints[0], ctrlPoints[1], ctrlPoints[2], ctrlPoints[3]);
+ return path2D;
+ }
+
+ @Override
+ public Path2D addTo(Path2D path2D, float t) {
+ Robot.Pos pos1 = line.getPos(t);
+ Robot.Pos pos2 = getPos(t);
+ path2D.quadTo(pos1.getX(), pos1.getY(), pos2.getX(), pos2.getY());
+ return path2D;
+ }
+}
diff --git a/src/org/jointheleague/graphical/robot/curves/Segment.java b/src/org/jointheleague/graphical/robot/curves/Segment.java
new file mode 100644
index 0000000..9d2da6d
--- /dev/null
+++ b/src/org/jointheleague/graphical/robot/curves/Segment.java
@@ -0,0 +1,76 @@
+package org.jointheleague.graphical.robot.curves;
+
+import com.sun.istack.internal.NotNull;
+import org.jointheleague.graphical.robot.Robot;
+
+import java.awt.geom.Path2D;
+
+public interface Segment {
+
+ /**
+ * Return the sub-segment of this segment that starts at 0 and ends at t.
+ * For t ≤ 0, returns a segment of size 0, and for t ≥ 1F,
+ * returns this.
+ *
+ * @param t a float value, normally between 0 and 1
+ * @return A sub-segment of this segment
+ */
+ Segment subSegment(float t);
+
+ /**
+ * Return the position on the segment at time t. If t ≤ 0,
+ * the start position of this segment is returned, and if t ≥ 1, the end
+ * position of this segment is returned.
+ *
+ * @param t a float value, normally between 0 and 1
+ * @return A position on this segment
+ */
+ Robot.Pos getPos(float t);
+
+ /**
+ * @return the angle in radians of the segment at the start
+ */
+ @NotNull
+ double getStartAngle();
+
+ /**
+ * @return the angle in radians of the segment at the end
+ */
+ double getEndAngle();
+
+ /**
+ * Gets the angle of the segment in radians at the position specified by time
+ *
+ * @param time the time that specifies a position on the segment
+ * @return the angle of the segment at time
+ */
+ double getAngle(float time);
+
+ /**
+ * The time a robot uses to trace a segment at a given speed is
+ * proportional to the segment's size.
+ *
+ * @return an estimate of the length of the segment
+ */
+ float getSize();
+
+ /**
+ * Adds the Segment to the end of a Path2D
+ *
+ * @param path2D a Path2D to which this segment is added.
+ * @return a Path2D
+ */
+ Path2D addTo(Path2D path2D);
+
+ /**
+ * Adds a sub-segment of this segment to the end of a Path2D
+ *
+ * @param path2D a Path2D to which the sub-segment is added
+ * @param t a float value, normally between 0 and 1, that
+ * specifies the sub-segment of this segment that is added
+ * @return a Path2D
+ * @see #subSegment(float)
+ */
+ Path2D addTo(Path2D path2D, float t);
+
+}
diff --git a/src/org/jointheleague/graphical/robot/batman.robi b/src/org/jointheleague/graphical/robot/res/batman.robi
similarity index 100%
rename from src/org/jointheleague/graphical/robot/batman.robi
rename to src/org/jointheleague/graphical/robot/res/batman.robi
diff --git a/src/org/jointheleague/graphical/robot/res/formersecretaryofstatecondoleezzarice.robi b/src/org/jointheleague/graphical/robot/res/formersecretaryofstatecondoleezzarice.robi
new file mode 100644
index 0000000..8d88af3
Binary files /dev/null and b/src/org/jointheleague/graphical/robot/res/formersecretaryofstatecondoleezzarice.robi differ
diff --git a/src/org/jointheleague/graphical/robot/res/june.robi b/src/org/jointheleague/graphical/robot/res/june.robi
new file mode 100644
index 0000000..f2082d7
Binary files /dev/null and b/src/org/jointheleague/graphical/robot/res/june.robi differ
diff --git a/src/org/jointheleague/graphical/robot/res/league_logo.png b/src/org/jointheleague/graphical/robot/res/league_logo.png
new file mode 100644
index 0000000..c880e71
Binary files /dev/null and b/src/org/jointheleague/graphical/robot/res/league_logo.png differ
diff --git a/src/org/jointheleague/graphical/robot/mini.robi b/src/org/jointheleague/graphical/robot/res/mini.robi
similarity index 100%
rename from src/org/jointheleague/graphical/robot/mini.robi
rename to src/org/jointheleague/graphical/robot/res/mini.robi
diff --git a/src/org/jointheleague/graphical/robot/rob.robi b/src/org/jointheleague/graphical/robot/res/rob.robi
similarity index 100%
rename from src/org/jointheleague/graphical/robot/rob.robi
rename to src/org/jointheleague/graphical/robot/res/rob.robi
diff --git a/src/org/jointheleague/graphical/robot/res/space.jpeg b/src/org/jointheleague/graphical/robot/res/space.jpeg
new file mode 100644
index 0000000..9a436bd
Binary files /dev/null and b/src/org/jointheleague/graphical/robot/res/space.jpeg differ
diff --git a/src/org/jointheleague/graphical/robot/vic.robi b/src/org/jointheleague/graphical/robot/res/vic.robi
similarity index 100%
rename from src/org/jointheleague/graphical/robot/vic.robi
rename to src/org/jointheleague/graphical/robot/res/vic.robi