Rounded corners for Arc Progress in react-native-svg - react-native

I've created an Arc Progress based on a tutorial (v. https://www.youtube.com/watch?v=UMvw20nRZls) and worked fine
But, since i have no experience using svg path, i'm struggling with my Arc trying to get it's corners rounded
Here is how the Arc's result so far
const { PI, cos, sin } = Math;
const { width } = Dimensions.get('window');
const size = width - 32;
const strokeWidth = 20;
const AnimatedPath = Animated.createAnimatedComponent(Path);
const r = (size - strokeWidth) / 2;
const cx = size / 2;
const cy = size / 2;
const A = PI + PI * 0.4;
const startAngle = PI + PI * 0.2;
const endAngle = 2 * PI - PI * 0.2;
// A rx ry x-axis-rotation large-arc-flag sweep-flag x y
const x1 = cx - r * cos(startAngle);
const y1 = -r * sin(startAngle) + cy;
const x2 = cx - r * cos(endAngle);
const y2 = -r * sin(endAngle) + cy;
const d = `M ${x1} ${y1} A ${r} ${r} 0 1 0 ${x2} ${y2}`;
<Path
stroke="#FFF"
fill="none"
strokeDasharray={`${circumference}, ${circumference}`}
{...{ d, strokeWidth }}
/>
And i expect to have the corners like this:
ps: i'm using an expo app, so , i needed to install react-native-svg with expo to work

You could set the strokeLinecap prop on the Path to round:
<Path
stroke="black"
fill="none"
strokeLinecap="round"
strokeDasharray={`${circumference}, ${circumference}`}
{...{d, strokeWidth}}
/>
The strokeLinecap prop specifies the shape to be used at the end of open subpaths when they are stroked. Can be either 'butt', 'square' or 'round'.
Source: https://github.com/react-native-community/react-native-svg#common-props.

Related

How to make a 2d shader working with ParallaxBackground node in Godot?

In my game I want to make a scrolling background with moving stars. I am using ParallaxBackground node with ParallaxLayer as a child, and the later has TextureRect child that display a 2d shader for the stars.
Nodes hierarchy:
ParallaxBackground -> StarsLayer -> Stars
Stars is the TextureRect and its rect_size equals the project window size.
Here is the 2d shader that it uses:
shader_type canvas_item;
uniform vec4 bg_color: hint_color;
float rand(vec2 st) {
return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.5453123);
}
void fragment() {
float size = 100.0;
float prob = 0.9;
vec2 pos = floor(1.0 / size * FRAGCOORD.xy);
float color = 0.0;
float starValue = rand(pos);
if (starValue > prob)
{
vec2 center = size * pos + vec2(size, size) * 0.5;
float t = 0.9 + 0.2 * sin(TIME * 8.0 + (starValue - prob) / (1.0 - prob) * 45.0);
color = 1.0 - distance(FRAGCOORD.xy, center) / (0.5 * size);
color = color * t / (abs(FRAGCOORD.y - center.y)) * t / (abs(FRAGCOORD.x - center.x));
}
else if (rand(SCREEN_UV.xy / 20.0) > 0.996)
{
float r = rand(SCREEN_UV.xy);
color = r * (0.85 * sin(TIME * (r * 5.0) + 720.0 * r) + 0.95);
}
COLOR = vec4(vec3(color),1.0) + bg_color;
}
Here is ParallaxBackground script:
extends ParallaxBackground
onready var stars_layer = $StarsLayer
var bg_offset = 0.0
func _ready():
stars_layer.motion_mirroring = Vector2(0, Helpers.WINDOW_SIZE.y)
func _process(delta):
bg_offset += 30 * delta
scroll_offset = Vector2(0, bg_offset)
The problem is that the stars are being showed but not moving at all.
Use motion_offset instead of scroll_offset
func _process(delta):
motion_offset += 30 * delta

React native SVG building pie chart with Path

I have a code that builds a SVG figure for a pie chart, using this function:
export const generateArc = (percentage: number, radius: number) => {
const a = (percentage * 2 * Math.PI) / 100 // angle (in radian) depends on percentage
const r = radius // radius of the circle
const rx = r
const ry = r
const xAxisRotation = 0
let largeArcFlag = 1
const sweepFlag = 1
const x = r + r * Math.sin(a)
const y = r - r * Math.cos(a)
if (percentage <= 50) {
largeArcFlag = 0
} else {
largeArcFlag = 1
}
return `A${rx} ${ry} ${xAxisRotation} ${largeArcFlag} ${sweepFlag} ${x} ${y}`
}
Everything works fine, except when percentage is 100, the chart disappears, you can look here
I feel like that there's some miscalculation, but i don't have much experience in such things with SVGS, and i can't figure it out.
The workarounds I've found are:
iOS: check if percentage is 100, then use 99.9, but that doesn't work for android (i've tested on real device, there's a little gap that's not filled, but on some emulators 99.9999 gives the full circle), you can check it in a snack
For both platform just use a full circle SVG instead, if percentage is 100, but i don't like that workaround
Thanks to #Robert Longson I've modified the function that generates arc a bit, so now it generates 2 arcs if percentage is 100
const generatePath = (percentage: number, radius: number) => {
if (percentage === 100) {
const x = radius
const y = radius
// in path x has to be 0 = starting point
return `M ${0}, ${y}
a ${x},${y} 0 1,1 ${radius * 2},0
a ${x},${y} 0 1,1 -${radius * 2},0
`
}
const a = (percentage * 2 * Math.PI) / 100 // angle (in radian) depends on percentage
const r = radius // radius of the circle
const rx = r
const ry = r
const xAxisRotation = 0
let largeArcFlag = 1
const sweepFlag = 1
const x = r + r * Math.sin(a)
const y = r - r * Math.cos(a)
if (percentage <= 50) {
largeArcFlag = 0
} else {
largeArcFlag = 1
}
return `M${radius} ${radius} L${radius} 0 A${rx} ${ry} ${xAxisRotation} ${largeArcFlag} ${sweepFlag} ${x} ${y} Z`
}

How to implement Processingview in React Native Expo?

Here I have implemented ProcessingView in Expo App. But I am getting this error "Check the render method of ProcessingView.". I am not able to find the solution. If anyone has idea then please guide me.
Here I have also attached the image of the screen
import React from 'react';
import { ProcessingView } from 'expo-processing';
export default class App extends React.Component {
render() {
return (
<ProcessingView style={{ flex: 1 }} sketch={this._sketch} />
);
}
_sketch = (p) => {
p.setup = () => {
p.strokeWeight(7);
}
const harom = (ax, ay, bx, by, level, ratio) => {
if (level <= 0) {
return;
}
const vx = bx - ax;
const vy = by - ay;
const nx = p.cos(p.PI / 3) * vx - p.sin(p.PI / 3) * vy;
const ny = p.sin(p.PI / 3) * vx + p.cos(p.PI / 3) * vy;
const cx = ax + nx;
const cy = ay + ny;
p.line(ax, ay, bx, by);
p.line(ax, ay, cx, cy);
p.line(cx, cy, bx, by);
harom(
ax * ratio + cx * (1 - ratio),
ay * ratio + cy * (1 - ratio),
ax * (1 - ratio) + bx * ratio,
ay * (1 - ratio) + by * ratio,
level - 1,
ratio);
}
p.draw = () => {
p.background(240);
harom(
p.width - 142, p.height - 142, 142, p.height - 142, 6,
(p.sin(0.0005 * Date.now() % (2 * p.PI)) + 1) / 2);
}
}
}

Path Tracing - Generate Camera Rays with a Left Handed coordinate system

Been having some issues implementing a camera for my renderer. As the question states,I would like to know the necessary steps to generate such a camera.With field of view and aspect ratio included.Its important that the Coordinate system be left handed such that -z pushes the camera away from the screen(as I understand it).I have tried looking online but most of the implementations are incomplete or have failed me.Any help is appreciated.Thank You.
I had trouble with this and took a long time to figure out. Here is the code for camera class.
#ifndef CAMERA_H_
#define CAMERA_H_
#include "common.h"
struct Camera {
Vec3fa position, direction;
float fovDist, aspectRatio;
double imgWidth, imgHeight;
Mat4 camMatrix;
Camera(Vec3fa pos, Vec3fa cRot, Vec3fa cDir, float cfov, int width, int height) {
position = pos;
aspectRatio = width / (float)height;
imgWidth = width;
imgHeight = height;
Vec3fa angle = Vec3fa(cRot.x, cRot.y, -cRot.z);
camMatrix.setRotationRadians(angle * M_PI / 180.0f);
direction = Vec3fa(0.0f, 0.0f, -1.0f);
camMatrix.rotateVect(direction);
fovDist = 2.0f * tan(M_PI * 0.5f * cfov / 180.0);
}
Vec3fa getRayDirection(float x, float y) {
Vec3fa delta = Vec3fa((x-0.5f) * fovDist * aspectRatio, (y-0.5f) * fovDist, 0.0f);
camMatrix.rotateVect(delta);
return (direction + delta);
}
};
#endif
Incase if you need the rotateVect() code in the Mat4 class
void Mat4::rotateVect(Vector3& vect) const
{
Vector3 tmp = vect;
vect.x = tmp.x * (*this)[0] + tmp.y * (*this)[4] + tmp.z * (*this)[8];
vect.y = tmp.x * (*this)[1] + tmp.y * (*this)[5] + tmp.z * (*this)[9];
vect.z = tmp.x * (*this)[2] + tmp.y * (*this)[6] + tmp.z * (*this)[10];
}
Here is our setRotationRadians code
void Mat4::setRotationRadians(Vector3 rotation)
{
const float cr = cos(rotation.x);
const float sr = sin(rotation.x);
const float cp = cos(rotation.y);
const float sp = sin(rotation.y);
const float cy = cos(rotation.z);
const float sy = sin(rotation.z);
(*this)[0] = (cp * cy);
(*this)[1] = (cp * sy);
(*this)[2] = (-sp);
const float srsp = sr * sp;
const float crsp = cr * sp;
(*this)[4] = (srsp * cy - cr * sy);
(*this)[5] = (srsp * sy + cr * cy);
(*this)[6] = (sr * cp);
(*this)[8] = (crsp * cy + sr * sy);
(*this)[9] = (crsp * sy - sr * cy);
(*this)[10] = (cr * cp);
}

three.js: Rotate around origin after panning camera

I have a plane/board, with a grid, that is about 1100 x 1100. I have panning, zooming, and rotating working except for the fact that the board moves back to the center of the screen after it has been panned. So, if I don't pan the board at all then everything works. After I pan the board it moves back to the center of the screen when I try to rotate it. I cannot figure out how to change the origin of the camera so that it rotates around the center of the board. It seems like it rotates around the center of the camera.
var radius = 1500, theta = 45 * 0.5, onMouseDownTheta = 45 * 0.5;
var fov = 45;
var mouse2D = new THREE.Vector3(0, 10000, 0.5);
cameraX = radius * Math.sin(THREE.Math.degToRad(theta));
cameraY = 1000;
cameraZ = radius * Math.cos(THREE.Math.degToRad(theta));
camera = new THREE.PerspectiveCamera(fov, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(cameraX, cameraY, cameraZ);
scene = new THREE.Scene();
camera.lookAt(scene.position);
render();
ThreeBoard.prototype.render = function() {
mouse2D.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse2D.y = - (event.clientY / window.innerHeight) * 2 + 1;
// rotate
if (isMouseDown && isShiftPressed && !isCtrlPressed) {
theta = ((event.pageX - mouse2D.x) * 0.5) + onMouseDownTheta;
cameraX = radius * Math.sin(THREE.Math.degToRad(theta));
cameraZ = radius * Math.cos(THREE.Math.degToRad(theta));
camera.position.set(cameraX, cameraY, cameraZ);
camera.lookAt(scene.position);
}
// pan
if (isMouseDown && isShiftPressed && isCtrlPressed) {
theta = ((event.pageX - mouse2D.x) * 0.5) + onMouseDownTheta;
cameraX += 10 * mouse2D.x;
// cameraY += 10;
cameraZ -= 10 * mouse2D.y;
camera.position.set(cameraX, cameraY, cameraZ);
// camera.lookAt(scene.position);
}
renderer.render(scene, camera);
};