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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
+

Constant Field Values

+

Contents

+
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
+

Deprecated API

+

Contents

+ +
+
+ + + +
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
+

How This API Document Is Organized

+
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+ +This help file applies to API documentation generated using the standard doclet.
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
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
+
+
Adds a KeyboardAdapter to the robot.
+
+
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 
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
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 
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
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 
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
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 
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
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 
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
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 
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
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 
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
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 
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
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 
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
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 
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
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 
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
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 
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
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 
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
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 
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
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 
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
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 
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
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 
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
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 
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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) + + + + + + + + + +<noscript> +<div>JavaScript is disabled on your browser.</div> +</noscript> +<h2>Frame Alert</h2> +<p>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 <a href="overview-summary.html">Non-frame version</a>.</p> + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + + +
+
org.jointheleague.graphical.robot
+

Interface Drawable

+
+
+
+ +
+
+ +
+
+ +
+
+ + +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + + +
+
org.jointheleague.graphical.robot
+

Class KeyboardAdapter

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + + +
+
org.jointheleague.graphical.robot
+

Class Line

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + + +
+
org.jointheleague.graphical.robot
+

Class Robot.Pos

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + + +
+
org.jointheleague.graphical.robot
+

Class Robot

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + + +
+
org.jointheleague.graphical.robot
+

Class RobotImage

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + + +
+
org.jointheleague.graphical.robot
+

Interface RobotInterface

+
+
+
+ +
+
+ +
+
+ +
+
+ + +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + + +
+
org.jointheleague.graphical.robot
+

Class RobotWindow

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + + +
+
org.jointheleague.graphical.robot.curves
+

Class Close

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + + +
+
org.jointheleague.graphical.robot.curves
+

Class Cubic

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + + +
+
org.jointheleague.graphical.robot.curves
+

Interface Drawable

+
+
+
+ +
+
+ +
+
+ +
+
+ + +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + + +
+
org.jointheleague.graphical.robot.curves
+

Class DynamicPath

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + + +
+
org.jointheleague.graphical.robot.curves
+

Class Line

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + + +
+
org.jointheleague.graphical.robot.curves
+

Class Move

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + + +
+
org.jointheleague.graphical.robot.curves
+

Class PartialPath

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + + +
+
org.jointheleague.graphical.robot.curves
+

Class Quad

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + + +
+
org.jointheleague.graphical.robot.curves
+

Interface Segment

+
+
+
+ +
+
+ +
+
+ +
+
+ + +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + +

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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
+

Package org.jointheleague.graphical.robot.curves

+
+
+ +
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
+

Hierarchy For Package org.jointheleague.graphical.robot.curves

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +

Interface Hierarchy

+ +
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + +

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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
+

Package org.jointheleague.graphical.robot

+
+
+ +
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
+

Hierarchy For Package org.jointheleague.graphical.robot

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +

Interface Hierarchy

+ +
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + +
All Classes
+
+

Packages

+ +
+

 

+ + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
+ + + + + + + + + + + + + + + + +
Packages 
PackageDescription
org.jointheleague.graphical.robot 
org.jointheleague.graphical.robot.curves 
+
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
+

Hierarchy For All Packages

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +

Interface Hierarchy

+ +
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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 + + + + + + + + +
+ + +
Skip navigation links
+ + + + +
+ + +
+

Serialized Form

+
+
+ +
+ +
+ + +
Skip navigation links
+ + + + +
+ + + + 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