ИГОРЬ

This commit is contained in:
Ivan Zinchenko 2025-01-23 06:14:33 +03:00
parent 86fb4f4d27
commit d15a4614d7
Signed by: zinch
GPG Key ID: 6D45AA2C8FD6A37E
15 changed files with 161 additions and 203 deletions

15
pom.xml
View File

@ -22,10 +22,6 @@
<artifactId>jakarta.jakartaee-web-api</artifactId>
<version>10.0.0</version>
<scope>provided</scope>
</dependency><dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.4.5.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
@ -39,9 +35,14 @@
<classifier>jakarta</classifier>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc11</artifactId>
<version>23.6.0.24.10</version>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>4.0.5</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.5</version>
</dependency>
</dependencies>

View File

@ -1,4 +1,4 @@
package me.zinch.jsf.model.entities;
package igorrr.jsf.model.entities;
public class HitResult {
double x;

View File

@ -1,4 +1,4 @@
package me.zinch.jsf.model.entities;
package igorrr.jsf.model.entities;
import jakarta.inject.Named;
import jakarta.persistence.Entity;

View File

@ -1,9 +1,8 @@
package me.zinch.jsf.model.entities;
package igorrr.jsf.model.entities;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.SessionScoped;
import jakarta.inject.Named;
import me.zinch.jsf.model.pages.FormState;
import java.io.Serializable;
import java.util.ArrayList;

View File

@ -1,19 +1,19 @@
package me.zinch.jsf.model.pages;
package igorrr.jsf.model.pages;
import jakarta.enterprise.context.RequestScoped;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.faces.context.FacesContext;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import me.zinch.jsf.model.entities.HitResult;
import me.zinch.jsf.model.entities.ShootResult;
import me.zinch.jsf.model.entities.Shoots;
import org.primefaces.PrimeFaces;
import igorrr.jsf.model.entities.HitResult;
import igorrr.jsf.model.entities.ShootResult;
import igorrr.jsf.model.entities.Shoots;
import services.ShootResultService;
import services.ShootService;
import java.io.Serializable;
@Named
@RequestScoped
@ApplicationScoped
public class FormState implements Serializable {
@Inject
Shoots shoots;
@ -23,7 +23,7 @@ public class FormState implements Serializable {
private double X = 0;
private double Y = 0;
private double R = 4;
private double R = 1;
public double getX() {
return X;
@ -49,6 +49,11 @@ public class FormState implements Serializable {
R = r;
}
public void changeX() {
FacesContext context = FacesContext.getCurrentInstance();
X = Double.parseDouble(context.getExternalContext().getRequestParameterMap().get("value"));
}
@Override
public String toString() {
return "FormState{" +

View File

@ -6,7 +6,7 @@ import jakarta.inject.Named;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
import me.zinch.jsf.model.entities.ShootResult;
import igorrr.jsf.model.entities.ShootResult;
@Named
@ApplicationScoped

View File

@ -2,8 +2,8 @@ package services;
public class ShootService {
public static boolean checkShoot(double x, double y, double r) {
if (x <= 0 && y <= 0 && (x*x + y*y <= r*r/4)) return true;
if (x >= 0 && y <= 0 && x <= r/2 && y >= -r) return true;
return x >= 0 && y >= 0 && y <= (-0.5 * x + r / 2);
if (x <= 0 && y <= 0 && x >= -r && y >= -r) return true;
if (x >= 0 && y <= 0 && x*x + y*y <= r*r) return true;
return x <= 0 && y >= 0 && y <= (0.5 * x + r / 2);
}
}

View File

@ -4,19 +4,18 @@
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
version="3.0">
<persistence-unit name="default">
<class>me.zinch.jsf.model.entities.ShootResult</class>
<class>igorrr.jsf.model.entities.ShootResult</class>
<properties>
<property name="jakarta.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
<property name="jakarta.persistence.jdbc.url" value="jdbc:oracle:thin:@//localhost:1521/FREEPDB1"/>
<property name="jakarta.persistence.jdbc.user" value="zinch"/>
<property name="jakarta.persistence.jdbc.password" value="zinch"/>
<property name="jakarta.persistence.jdbc.driver" value="org.postgresql.Driver"/>
<property name="jakarta.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/igor"/>
<property name="jakarta.persistence.jdbc.user" value="postgres"/>
<property name="jakarta.persistence.jdbc.password" value="NHYOUX8VDGlSukoaX2ydo6rHrYYILZSZ"/>
<property name="jakarta.persistence.schema-generation.database.action" value="drop-and-create"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.highlight_sql" value="true"/>
<property name="eclipselink.logging.level" value="FINE" />
<property name="eclipselink.ddl-generation" value="create-tables" />
</properties>
</persistence-unit>
</persistence>

View File

@ -9,7 +9,7 @@
<link href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&amp;display=swap" rel="stylesheet" />
<style>
body {
font-family: Inter, sans-serif;
font-family: "Times New Roman", serif;
}
</style>
<title>ЛАБА 3</title>

View File

@ -4,16 +4,53 @@
xmlns:h="jakarta.faces.html"
xmlns:ui="jakarta.faces.facelets">
<ui:component>
<canvas id="targetCanvas"/>
<h:outputScript name="p5.min.js" />
<script>
let r = #{formState.r};
let points = #{shoots.getJson()};
function transformSvgToPlane(svgX, svgY, r) {
let planeX = (svgX - 150) / (120 / r);
let planeY = (150 - svgY) / (120 / r);
return {
x: planeX,
y: planeY
};
}
document.getElementById("form:r_input").addEventListener("change", (e) => r = isNaN(Number(e.target.value)) ? 1 : Number(e.target.value))
function drawPoint(x, y, r, result) {
let circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
circle.setAttribute("cx", x * 60 * 2 / r + 150);
circle.setAttribute("cy", -y * 60 * 2 / r + 150);
circle.setAttribute("r", 3);
circle.style.fill = result ? "#09a53d" : "#a50909";
svg.appendChild(circle);
}
function updatePoints() {
points = JSON.parse(document.getElementById("form:points").value);
points.forEach(e => drawPoint(e.x, e.y, r, e.hit));
}
const svg = document.getElementById("svg");
svg.addEventListener("click", (event) => {
let point = svg.createSVGPoint();
point.x = event.clientX;
point.y = event.clientY;
let ctm = svg.getScreenCTM();
if (ctm) {
let invertedCTM = ctm.inverse();
let svgPoint = point.matrixTransform(invertedCTM);
let planeCoords = transformSvgToPlane(svgPoint.x, svgPoint.y, r);
document.getElementById("form:y_input").value = planeCoords.y.toFixed(1);
document.getElementById("form:r_input").value = r;
document.getElementById("form:cmd_button").click();
}
});
</script>
<h:outputScript name="target.js" />
</ui:component>
</html>

View File

@ -11,49 +11,91 @@
</h:head>
<h:body>
<h:form id="form">
<p:button outcome="index" value="К часикам"/>
<h:button outcome="index" value="Обратно"/>
<h:inputHidden id="points" value="#{shoots.json}"/>
<div style="display: flex; flex-direction: row; gap: 2em;">
<div style="display: flex; flex-direction: row; gap: 32px;">
<div id="targetContainer">
<svg id="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300.71 300.71" width="300px" height="300px">
<line y1="150.71" x2="300" y2="150.71" style="fill: none; stroke: #000720;"/>
<line x1="150" y1=".71" x2="150" y2="300.71" style="fill: none; stroke: #000720;"/>
<text transform="translate(290 145.71)" style="font-family: ArialMT, Arial; font-size: 12px; isolation: isolate;"><tspan x="0" y="0">X</tspan></text>
<text transform="translate(155 10.71)" style="font-family: ArialMT, Arial; font-size: 12px; isolation: isolate; letter-spacing: -.02em;"><tspan x="0" y="0">Y</tspan></text>
<text transform="translate(251.76 145.71)" style="font-family: ArialMT, Arial; font-size: 12px; isolation: isolate;"><tspan x="0" y="0">R</tspan></text>
<text transform="translate(190 145.71)" style="font-family: ArialMT, Arial; font-size: 12px; isolation: isolate;"><tspan x="0" y="0">R/2</tspan></text>
<text transform="translate(80 145.71)" style="font-family: ArialMT, Arial; font-size: 12px; isolation: isolate;"><tspan x="0" y="0">-R/2</tspan></text>
<text transform="translate(25.09 145.71)" style="font-family: ArialMT, Arial; font-size: 12px; isolation: isolate;"><tspan x="0" y="0">-R</tspan></text>
<text transform="translate(155 40.71)" style="font-family: ArialMT, Arial; font-size: 12px; isolation: isolate;"><tspan x="0" y="0">R</tspan></text>
<text transform="translate(155 90.71)" style="font-family: ArialMT, Arial; font-size: 12px; isolation: isolate;"><tspan x="0" y="0">R/2</tspan></text>
<text transform="translate(155 210.71)" style="font-family: ArialMT, Arial; font-size: 12px; isolation: isolate;"><tspan x="0" y="0">-R/2</tspan></text>
<text transform="translate(156.22 257.93)" style="font-family: ArialMT, Arial; font-size: 12px; isolation: isolate;"><tspan x="0" y="0">-R</tspan></text>
<rect x="45.5" y="150.71" width="104.5" height="104.5" style="fill: rgba(0, 0, 255, .6);"/>
<polygon points="300 150.71 295 155.71 295 145.71 300 150.71" style="fill: #000720; stroke: #000720;"/>
<polygon points="150 .71 145 5.71 155 5.71 150 .71" style="fill: #000720; stroke: #000720;"/>
<polygon points="45.5 150.71 150 90.71 150 150.71 45.5 150.71" style="fill: rgba(0, 0, 255, .6);"/>
<path d="m150,150.71v104.5c50.9,0,101.8-39.8,101.8-104.5h-101.8Z" style="fill: rgba(0, 0, 255, .6);"/>
</svg>
</div>
<div>
<h:panelGrid columns="1" style="margin-bottom: 10px">
<h:outputLabel for="x_input">X:</h:outputLabel>
<p:inputText required="true" id="x_input" value="#{formState.x}" validatorMessage="Значение X должно быть между -5 и 5.">
<f:validateLongRange minimum="-5" maximum="5"/>
</p:inputText>
<p:slider for="x_input" minValue="-5" maxValue="5" step="0.001"/>
<p:message for="x_input" id="x_message"/>
</h:panelGrid>
<div style="display: flex; gap: 10px;">
<span>X: #{formState.x}</span>
<h:commandLink value="-5" action="#{formState.changeX}">
<f:param name="value" value="-5" />
</h:commandLink>
<h:commandLink value="-4" action="#{formState.changeX}">
<f:param name="value" value="-4" />
</h:commandLink>
<h:commandLink value="-3" action="#{formState.changeX}">
<f:param name="value" value="-3" />
</h:commandLink>
<h:commandLink value="-2" action="#{formState.changeX}">
<f:param name="value" value="-2" />
</h:commandLink>
<h:commandLink value="-1" action="#{formState.changeX}">
<f:param name="value" value="-1" />
</h:commandLink>
<h:commandLink value="0" action="#{formState.changeX}">
<f:param name="value" value="0" />
</h:commandLink>
<h:commandLink value="1" action="#{formState.changeX}">
<f:param name="value" value="1" />
</h:commandLink>
<h:commandLink value="2" action="#{formState.changeX}">
<f:param name="value" value="2" />
</h:commandLink>
<h:commandLink value="3" action="#{formState.changeX}">
<f:param name="value" value="3" />
</h:commandLink>
</div>
<h:panelGrid columns="1" style="margin-bottom: 10px">
<h:outputLabel for="y_input">Y:</h:outputLabel>
<p:inputText required="true" id="y_input" value="#{formState.y}" validatorMessage="Значение Y должно быть между -3 и 5.">
<h:inputText required="true" id="y_input" value="#{formState.y}" validatorMessage="Значение Y должно быть между -3 и 5.">
<f:validateLongRange minimum="-3" maximum="5"/>
</p:inputText>
<p:message for="y_input" id="y_message"/>
</h:inputText>
<h:message for="y_input" id="y_message"/>
</h:panelGrid>
<h:panelGrid columns="1" style="margin-bottom: 10px">
<h:outputLabel for="r_input">R:</h:outputLabel>
<p:inputText required="true" id="r_input" value="#{formState.r}" validatorMessage="Значение R должно быть между 1 и 4.">
<f:validateLongRange minimum="1" maximum="4"/>
<f:validateLongRange minimum="-5" maximum="5"/>
</p:inputText>
<p:slider for="r_input" minValue="1" maxValue="4" step="0.25"/>
<p:message for="r_input" id="r_message"/>
</h:panelGrid>
</div>
<div id="targetContainer">
<p:dataTable var="shoot" value="#{shoots.shoots}" id="table" size="small" style="height: 50dvh; overflow-y: auto;">
<p:column field="x" headerText="x"/>
<p:column field="y" headerText="y"/>
<p:column field="r" headerText="r"/>
<p:column field="shoot" headerText="hit"/>
</p:dataTable>
</div>
</div>
<ui:include src="components/target.xhtml"/>
<p:dataTable var="shoot" value="#{shoots.shoots}" id="table" size="small" style="height: 30dvh; overflow-y: auto;">
<p:column filterable="false" sortable="false" field="x" headerText="x"/>
<p:column filterable="false" sortable="false" field="y" headerText="y"/>
<p:column filterable="false" sortable="false" field="r" headerText="r"/>
<p:column filterable="false" sortable="false" field="shoot" headerText="hit"/>
</p:dataTable>
<p:commandButton value="Отправить"
action="#{formState.submit}"
validateClient="true"
id="cmd_button"
update="x_message y_message r_message table points points"
update="x_message y_message r_message table points"
oncomplete="updatePoints()"/>
<ui:include src="components/target.xhtml"/>
</h:form>
</h:body>
</f:view>

View File

@ -8,23 +8,17 @@
<f:view contentType="text/html;charset=UTF-8" encoding="UTF-8">
<h:head>
<ui:include src="components/head.xhtml"/>
<style>
.zin--header {
margin: 0 .5em;
font-weight: bold;
}
</style>
</h:head>
<h:body>
<div style="text-align: center;">
<h:panelGrid columns="3" style="margin-bottom: 10px">
<h:outputText styleClass="zin--header" value="Зинченко Иван Николаевич"/>
<h:outputText styleClass="zin--header" value="P3212"/>
<h:outputText styleClass="zin--header" value="12023"/>
<div>
<h:panelGrid columns="1" style="margin-bottom: 10px">
<h:outputText value="Елхимов Игорь Денисович"/>
<h:outputText value="P3212"/>
<h:outputText value="12052"/>
</h:panelGrid>
<canvas id="canvas" width="500px" height="500px"/>
<div id="time"></div>
<div id="date"></div>
<p:button outcome="form" value="К форме"/>
<h:button outcome="form" value="Форма"/>
<h:outputScript name="clock.js"/>
</div>
</h:body>

View File

@ -1,80 +1,24 @@
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let radius = canvas.height / 2;
ctx.translate(radius, radius);
radius = radius * 0.90
drawClock();
setInterval(drawClock, 6000);
setInterval(drawClock, 10000);
function drawClock() {
drawFace(ctx, radius);
drawNumbers(ctx, radius);
drawTime(ctx, radius);
displayDate();
updateTime();
}
function drawFace(ctx, radius) {
const grad = ctx.createRadialGradient(0,0,radius*0.95, 0,0,radius*1.05);
grad.addColorStop(0, '#2196f3');
grad.addColorStop(0.5, '#4baaf5');
grad.addColorStop(1, '#2196f3');
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2*Math.PI);
ctx.fillStyle = 'white';
ctx.fill();
ctx.strokeStyle = grad;
ctx.lineWidth = radius*0.1;
ctx.stroke();
ctx.beginPath();
ctx.arc(0, 0, radius*0.1, 0, 2*Math.PI);
ctx.fillStyle = '#333';
ctx.fill();
}
function drawNumbers(ctx, radius) {
ctx.font = radius*0.15 + "px impact";
ctx.textBaseline="middle";
ctx.textAlign="center";
for(let num = 1; num < 13; num++){
let ang = num * Math.PI / 6;
ctx.rotate(ang);
ctx.translate(0, -radius*0.85);
ctx.rotate(-ang);
ctx.fillText(num.toString(), 0, 0);
ctx.rotate(ang);
ctx.translate(0, radius*0.85);
ctx.rotate(-ang);
}
}
function drawTime(ctx, radius){
function getCurrentTime() {
const now = new Date();
let hour = now.getHours();
let minute = now.getMinutes();
let second = now.getSeconds();
//hour
hour=hour%12;
hour=(hour*Math.PI/6)+
(minute*Math.PI/(6*60))+
(second*Math.PI/(360*60));
drawHand(ctx, hour, radius*0.5, radius*0.07);
//minute
minute=(minute*Math.PI/30)+(second*Math.PI/(30*60));
drawHand(ctx, minute, radius*0.8, radius*0.07);
// second
second=(second*Math.PI/30);
drawHand(ctx, second, radius*0.9, radius*0.02);
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
return `${hours}:${minutes}:${seconds}`;
}
function drawHand(ctx, pos, length, width) {
ctx.beginPath();
ctx.lineWidth = width;
ctx.lineCap = "round";
ctx.moveTo(0,0);
ctx.rotate(pos);
ctx.lineTo(0, -length);
ctx.stroke();
ctx.rotate(-pos);
function updateTime() {
const timeDiv = document.getElementById('time');
if (timeDiv) {
timeDiv.textContent = getCurrentTime();
}
}
function displayDate() {

File diff suppressed because one or more lines are too long

View File

@ -1,61 +0,0 @@
const w = 300;
const h = 300;
const inaccuracy = 0.9; // чтобы не в притык канвасу
const fiss = 5; // кол-во рисок
document.getElementById("form:r_input").addEventListener('change', (e) => {
let value = Number(e.target.value);
if (isNaN(value)) return;
r = Math.max(Math.min(value, 4), 1);
})
const targetCanvas = document.querySelector("#targetCanvas");
function setup() {
const canvas = createCanvas(w, h, WEBGL, targetCanvas);
canvas.parent('targetContainer');
smooth();
}
function draw() {
background(255);
const wv = w/fiss/2;
const hv = h/fiss/2;
// фигуры
fill('#e7194c');
stroke(0, 0);
arc(0, 0, wv * r * inaccuracy, wv * r * inaccuracy, HALF_PI, PI);
triangle(0,0, 0,-hv * r/2 * inaccuracy, wv * inaccuracy * r, 0);
rect(0, 0, wv * r/2 * inaccuracy, hv * r * inaccuracy);
// координатная сетка
fill(255, 215, 0);
stroke(255, 215, 0);
strokeWeight(3);
line(0, -h/2, 0, h/2);
line(-w/2, 0, w/2, 0);
strokeWeight(1);
for (let i = -fiss; i <= fiss; i++) {
line(hv * i * inaccuracy, -10, hv * i * inaccuracy, 10);
line(-10, wv * i * inaccuracy, 10, wv * i * inaccuracy);
}
strokeWeight(10);
for (const p of points) {
stroke(p.hit ? "#34850b" : "#b50f37");
point(p.x * wv * inaccuracy, -p.y * wv * inaccuracy);
}
};
function mouseClicked(event) {
if (event?.target.tagName === 'CANVAS' && mouseX !== 0 && mouseY !== 0) {
const x = (mouseX - w/2) / 24 * inaccuracy;
const y = -(mouseY - h/2) / 24 * inaccuracy;
console.log(Math.min(5, Math.max(-3, x)), Math.min(5, Math.max(-3, y)));
document.getElementById("form:x_input").value = x.toFixed(3);
document.getElementById("form:y_input").value = y.toFixed(3);
document.getElementById("form:cmd_button").click();
}
}